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 2008 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * Map file parsing. 33 */ 34 #include <fcntl.h> 35 #include <string.h> 36 #include <stdio.h> 37 #include <unistd.h> 38 #include <sys/stat.h> 39 #include <errno.h> 40 #include <limits.h> 41 #include <dirent.h> 42 #include <ctype.h> 43 #include <elfcap.h> 44 #include <debug.h> 45 #include "msg.h" 46 #include "_libld.h" 47 48 #if defined(_ELF64) 49 #define STRTOADDR strtoull 50 #define XWORD_MAX ULLONG_MAX 51 #else /* Elf32 */ 52 #define STRTOADDR strtoul 53 #define XWORD_MAX UINT_MAX 54 #endif /* _ELF64 */ 55 56 typedef enum { 57 TK_STRING, TK_COLON, TK_SEMICOLON, TK_EQUAL, 58 TK_ATSIGN, TK_DASH, TK_LEFTBKT, TK_RIGHTBKT, 59 TK_PIPE, TK_EOF 60 } Token; /* Possible return values from gettoken. */ 61 62 63 static char *Mapspace; /* Malloc space holding map file. */ 64 static ulong_t Line_num; /* Current map file line number. */ 65 static char *Start_tok; /* First character of current token. */ 66 static char *nextchr; /* Next char in mapfile to examine. */ 67 68 /* 69 * Convert a string to lowercase. 70 */ 71 static void 72 lowercase(char *str) 73 { 74 while (*str = tolower(*str)) 75 str++; 76 } 77 78 /* 79 * Get a token from the mapfile. 80 */ 81 static Token 82 gettoken(Ofl_desc *ofl, const char *mapfile) 83 { 84 static char oldchr = '\0'; /* Char at end of current token. */ 85 char *end; /* End of the current token. */ 86 87 /* Cycle through the characters looking for tokens. */ 88 for (;;) { 89 if (oldchr != '\0') { 90 *nextchr = oldchr; 91 oldchr = '\0'; 92 } 93 if (!isascii(*nextchr) || 94 (!isprint(*nextchr) && !isspace(*nextchr) && 95 (*nextchr != '\0'))) { 96 eprintf(ofl->ofl_lml, ERR_FATAL, 97 MSG_INTL(MSG_MAP_ILLCHAR), mapfile, 98 EC_XWORD(Line_num), *((uchar_t *)nextchr)); 99 /* LINTED */ 100 return ((Token)S_ERROR); 101 } 102 switch (*nextchr) { 103 case '\0': /* End of file. */ 104 return (TK_EOF); 105 case ' ': /* White space. */ 106 case '\t': 107 nextchr++; 108 break; 109 case '\n': /* White space too, but bump line number. */ 110 nextchr++; 111 Line_num++; 112 break; 113 case '#': /* Comment. */ 114 while (*nextchr != '\n' && *nextchr != '\0') 115 nextchr++; 116 break; 117 case ':': 118 nextchr++; 119 return (TK_COLON); 120 case ';': 121 nextchr++; 122 return (TK_SEMICOLON); 123 case '=': 124 nextchr++; 125 return (TK_EQUAL); 126 case '@': 127 nextchr++; 128 return (TK_ATSIGN); 129 case '-': 130 nextchr++; 131 return (TK_DASH); 132 case '|': 133 nextchr++; 134 return (TK_PIPE); 135 case '{': 136 nextchr++; 137 return (TK_LEFTBKT); 138 case '}': 139 nextchr++; 140 return (TK_RIGHTBKT); 141 case '"': 142 Start_tok = ++nextchr; 143 if (((end = strpbrk(nextchr, 144 MSG_ORIG(MSG_MAP_TOK_1))) == NULL) || 145 (*end != '"')) { 146 eprintf(ofl->ofl_lml, ERR_FATAL, 147 MSG_INTL(MSG_MAP_NOTERM), mapfile, 148 EC_XWORD(Line_num)); 149 /* LINTED */ 150 return ((Token)S_ERROR); 151 } 152 *end = '\0'; 153 nextchr = end + 1; 154 return (TK_STRING); 155 default: /* string. */ 156 Start_tok = nextchr; /* CSTYLED */ 157 end = strpbrk(nextchr, MSG_ORIG(MSG_MAP_TOK_2)); 158 if (end == NULL) 159 nextchr = Start_tok + strlen(Start_tok); 160 else { 161 nextchr = end; 162 oldchr = *nextchr; 163 *nextchr = '\0'; 164 } 165 return (TK_STRING); 166 } 167 } 168 } 169 170 /* 171 * Process a hardware/software capabilities segment declaration definition. 172 * hwcap_1 = val,... [ OVERRIDE ] 173 * sfcap_1 = val,... [ OVERRIDE ] 174 * 175 * The values can be defined as a list of machine specify tokens, or numerics. 176 * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example: 177 * 178 * #define AV_386_FPU 0x0001 is represented as FPU 179 * #define AV_386_TSC 0x0002 " " " " TSC 180 * 181 * Or, the above two capabilities could be represented as V0x3. Note, the 182 * OVERRIDE flag is used to insure that only those values provided via this 183 * mapfile entry are recorded in the final image, ie. this overrides any 184 * hardware capabilities that may be defined in the objects read as part of this 185 * link-edit. Specifying: 186 * 187 * V0x0 OVERRIDE 188 * 189 * effectively removes any capabilities information from the final image. 190 */ 191 static uintptr_t 192 map_cap(const char *mapfile, Word type, Ofl_desc *ofl) 193 { 194 Token tok; /* Current token. */ 195 Xword number; 196 int used = 0; 197 198 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 199 /* LINTED */ 200 if (tok == (Token)S_ERROR) 201 return (S_ERROR); 202 if (tok == TK_EOF) { 203 eprintf(ofl->ofl_lml, ERR_FATAL, 204 MSG_INTL(MSG_MAP_PREMEOF), mapfile, 205 EC_XWORD(Line_num)); 206 return (S_ERROR); 207 } 208 if (tok != TK_STRING) { 209 eprintf(ofl->ofl_lml, ERR_FATAL, 210 MSG_INTL(MSG_MAP_EXPSEGATT), mapfile, 211 EC_XWORD(Line_num)); 212 return (S_ERROR); 213 } 214 215 lowercase(Start_tok); 216 217 /* 218 * First, determine if the token represents the reserved 219 * OVERRIDE keyword. 220 */ 221 if (strncmp(Start_tok, MSG_ORIG(MSG_MAP_OVERRIDE), 222 MSG_MAP_OVERRIDE_SIZE) == 0) { 223 if (type == CA_SUNW_HW_1) 224 ofl->ofl_flags1 |= FLG_OF1_OVHWCAP; 225 else 226 ofl->ofl_flags1 |= FLG_OF1_OVSFCAP; 227 used++; 228 continue; 229 } 230 231 /* 232 * Next, determine if the token represents a machine specific 233 * hardware capability, or a generic software capability. 234 */ 235 if (type == CA_SUNW_HW_1) { 236 if ((number = (Xword)elfcap_hw1_from_str( 237 ELFCAP_STYLE_LC, Start_tok, 238 ld_targ.t_m.m_mach)) != 0) { 239 ofl->ofl_hwcap_1 |= number; 240 used++; 241 continue; 242 } 243 } else { 244 if ((number = (Xword)elfcap_sf1_from_str( 245 ELFCAP_STYLE_LC, Start_tok, 246 ld_targ.t_m.m_mach)) != 0) { 247 ofl->ofl_sfcap_1 |= number; 248 used++; 249 continue; 250 } 251 } 252 253 /* 254 * Next, determine if the token represents a numeric value. 255 */ 256 if (Start_tok[0] == 'v') { 257 char *end_tok; 258 259 errno = 0; 260 number = (Xword)strtoul(&Start_tok[1], &end_tok, 0); 261 if (errno) { 262 int err = errno; 263 eprintf(ofl->ofl_lml, ERR_FATAL, 264 MSG_INTL(MSG_MAP_BADCAPVAL), 265 mapfile, EC_XWORD(Line_num), Start_tok, 266 strerror(err)); 267 return (S_ERROR); 268 } 269 if (end_tok != strchr(Start_tok, '\0')) { 270 eprintf(ofl->ofl_lml, ERR_FATAL, 271 MSG_INTL(MSG_MAP_BADCAPVAL), mapfile, 272 EC_XWORD(Line_num), Start_tok, 273 MSG_INTL(MSG_MAP_NOBADFRM)); 274 return (S_ERROR); 275 } 276 277 if (type == CA_SUNW_HW_1) 278 ofl->ofl_hwcap_1 |= number; 279 else 280 ofl->ofl_sfcap_1 |= number; 281 used++; 282 continue; 283 } 284 285 /* 286 * We have an unknown token. 287 */ 288 used++; 289 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_MAP_UNKCAPATTR), 290 mapfile, EC_XWORD(Line_num), Start_tok); 291 return (S_ERROR); 292 } 293 294 /* 295 * Catch any empty declarations, and indicate any software capabilities 296 * have been initialized if necessary. 297 */ 298 if (used == 0) { 299 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_MAP_EMPTYCAP), 300 mapfile, EC_XWORD(Line_num)); 301 } else if (type == CA_SUNW_SF_1) { 302 Lword badsf1; 303 304 /* 305 * Note, hardware capabilities, beyond the tokens that are 306 * presently known, can be accepted using the V0xXXX notation, 307 * and as these simply get or'd into the output image, we allow 308 * any values to be supplied. Software capability tokens 309 * however, have an algorithm of acceptance and update (see 310 * sf1_cap() in files.c). Therefore only allow software 311 * capabilities that are known. 312 */ 313 if ((badsf1 = (ofl->ofl_sfcap_1 & ~SF1_SUNW_MASK)) != 0) { 314 eprintf(ofl->ofl_lml, ERR_WARNING, 315 MSG_INTL(MSG_MAP_BADSF1), mapfile, 316 EC_XWORD(Line_num), EC_LWORD(badsf1)); 317 ofl->ofl_sfcap_1 &= SF1_SUNW_MASK; 318 } 319 if (ofl->ofl_sfcap_1 == SF1_SUNW_FPUSED) { 320 eprintf(ofl->ofl_lml, ERR_WARNING, 321 MSG_INTL(MSG_FIL_BADSF1), mapfile, 322 EC_XWORD(Line_num), EC_LWORD(SF1_SUNW_FPUSED)); 323 ofl->ofl_sfcap_1 = 0; 324 } 325 } 326 return (1); 327 } 328 329 /* 330 * Common segment error checking. 331 */ 332 static Boolean 333 seg_check(const char *mapfile, Sg_desc *sgp, Ofl_desc *ofl, Boolean b_type, 334 Word p_type) 335 { 336 if (b_type) { 337 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_MAP_MOREONCE), 338 mapfile, EC_XWORD(Line_num), MSG_INTL(MSG_MAP_SEGTYP)); 339 return (FALSE); 340 } 341 if ((sgp->sg_flags & FLG_SG_TYPE) && (sgp->sg_phdr.p_type != p_type)) { 342 eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_MAP_REDEFATT), 343 mapfile, EC_XWORD(Line_num), MSG_INTL(MSG_MAP_SEGTYP), 344 sgp->sg_name); 345 } 346 return (TRUE); 347 } 348 349 /* 350 * Process a mapfile segment declaration definition. 351 * segment_name = segment_attribute; 352 * segment_attribute : segment_type segment_flags virtual_addr 353 * physical_addr length alignment 354 */ 355 static uintptr_t 356 map_equal(const char *mapfile, Sg_desc *sgp, Ofl_desc *ofl) 357 { 358 Token tok; /* Current token. */ 359 Boolean b_type = FALSE; /* True if seg types found. */ 360 Boolean b_flags = FALSE; /* True if seg flags found. */ 361 Boolean b_len = FALSE; /* True if seg length found. */ 362 Boolean b_round = FALSE; /* True if seg rounding found. */ 363 Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */ 364 Boolean b_paddr = FALSE; /* True if seg physical addr found. */ 365 Boolean b_align = FALSE; /* True if seg alignment found. */ 366 367 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 368 /* LINTED */ 369 if (tok == (Token)S_ERROR) 370 return (S_ERROR); 371 if (tok == TK_EOF) { 372 eprintf(ofl->ofl_lml, ERR_FATAL, 373 MSG_INTL(MSG_MAP_PREMEOF), mapfile, 374 EC_XWORD(Line_num)); 375 return (S_ERROR); 376 } 377 if (tok != TK_STRING) { 378 eprintf(ofl->ofl_lml, ERR_FATAL, 379 MSG_INTL(MSG_MAP_EXPSEGATT), mapfile, 380 EC_XWORD(Line_num)); 381 return (S_ERROR); 382 } 383 384 lowercase(Start_tok); 385 386 /* 387 * Segment type. Users are permitted to define PT_LOAD, 388 * PT_NOTE, PT_STACK and PT_NULL segments. Other segment types 389 * are only defined in seg_desc[]. 390 */ 391 if (strcmp(Start_tok, MSG_ORIG(MSG_MAP_LOAD)) == 0) { 392 if ((b_type = seg_check(mapfile, sgp, ofl, b_type, 393 PT_LOAD)) == FALSE) 394 return (S_ERROR); 395 396 sgp->sg_phdr.p_type = PT_LOAD; 397 sgp->sg_flags |= FLG_SG_TYPE; 398 399 } else if (strcmp(Start_tok, MSG_ORIG(MSG_MAP_STACK)) == 0) { 400 if ((b_type = seg_check(mapfile, sgp, ofl, b_type, 401 PT_SUNWSTACK)) == FALSE) 402 return (S_ERROR); 403 404 sgp->sg_phdr.p_type = PT_SUNWSTACK; 405 sgp->sg_flags |= (FLG_SG_TYPE | FLG_SG_EMPTY); 406 407 } else if (strcmp(Start_tok, MSG_ORIG(MSG_MAP_NULL)) == 0) { 408 if ((b_type = seg_check(mapfile, sgp, ofl, b_type, 409 PT_NULL)) == FALSE) 410 return (S_ERROR); 411 412 sgp->sg_phdr.p_type = PT_NULL; 413 sgp->sg_flags |= FLG_SG_TYPE; 414 415 } else if (strcmp(Start_tok, MSG_ORIG(MSG_MAP_NOTE)) == 0) { 416 if ((b_type = seg_check(mapfile, sgp, ofl, b_type, 417 PT_NOTE)) == FALSE) 418 return (S_ERROR); 419 420 sgp->sg_phdr.p_type = PT_NOTE; 421 sgp->sg_flags |= FLG_SG_TYPE; 422 } 423 424 /* Segment Flags. */ 425 426 else if (*Start_tok == '?') { 427 Word tmp_flags = 0; 428 char *flag_tok = Start_tok + 1; 429 430 if (b_flags) { 431 eprintf(ofl->ofl_lml, ERR_FATAL, 432 MSG_INTL(MSG_MAP_MOREONCE), mapfile, 433 EC_XWORD(Line_num), 434 MSG_INTL(MSG_MAP_SEGFLAG)); 435 return (S_ERROR); 436 } 437 438 /* 439 * If ? has nothing following leave the flags cleared, 440 * otherwise or in any flags specified. 441 */ 442 if (*flag_tok) { 443 while (*flag_tok) { 444 switch (*flag_tok) { 445 case 'r': 446 tmp_flags |= PF_R; 447 break; 448 case 'w': 449 tmp_flags |= PF_W; 450 break; 451 case 'x': 452 tmp_flags |= PF_X; 453 break; 454 case 'e': 455 sgp->sg_flags |= FLG_SG_EMPTY; 456 break; 457 case 'o': 458 sgp->sg_flags |= FLG_SG_ORDER; 459 ofl->ofl_flags |= 460 FLG_OF_SEGORDER; 461 break; 462 case 'n': 463 sgp->sg_flags |= FLG_SG_NOHDR; 464 break; 465 default: 466 eprintf(ofl->ofl_lml, ERR_FATAL, 467 MSG_INTL(MSG_MAP_UNKSEGFLG), 468 mapfile, EC_XWORD(Line_num), 469 *flag_tok); 470 return (S_ERROR); 471 } 472 flag_tok++; 473 } 474 } 475 /* 476 * Warn when changing flags except when we're 477 * adding or removing "X" from a RW PT_LOAD 478 * segment. 479 */ 480 if ((sgp->sg_flags & FLG_SG_FLAGS) && 481 (sgp->sg_phdr.p_flags != tmp_flags) && 482 !(sgp->sg_phdr.p_type == PT_LOAD && 483 (tmp_flags & (PF_R|PF_W)) == (PF_R|PF_W) && 484 (tmp_flags ^ sgp->sg_phdr.p_flags) == PF_X)) { 485 eprintf(ofl->ofl_lml, ERR_WARNING, 486 MSG_INTL(MSG_MAP_REDEFATT), mapfile, 487 EC_XWORD(Line_num), 488 MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name); 489 } 490 sgp->sg_flags |= FLG_SG_FLAGS; 491 sgp->sg_phdr.p_flags = tmp_flags; 492 b_flags = TRUE; 493 } 494 495 496 /* Segment address, length, alignment or rounding number. */ 497 498 else if ((Start_tok[0] == 'l') || (Start_tok[0] == 'v') || 499 (Start_tok[0] == 'a') || (Start_tok[0] == 'p') || 500 (Start_tok[0] == 'r')) { 501 char *end_tok; 502 Xword number; 503 504 if ((number = (Xword)STRTOADDR(&Start_tok[1], &end_tok, 505 0)) >= XWORD_MAX) { 506 eprintf(ofl->ofl_lml, ERR_FATAL, 507 MSG_INTL(MSG_MAP_SEGADDR), mapfile, 508 EC_XWORD(Line_num), Start_tok, 509 MSG_INTL(MSG_MAP_EXCLIMIT)); 510 return (S_ERROR); 511 } 512 513 if (end_tok != strchr(Start_tok, '\0')) { 514 eprintf(ofl->ofl_lml, ERR_FATAL, 515 MSG_INTL(MSG_MAP_SEGADDR), mapfile, 516 EC_XWORD(Line_num), Start_tok, 517 MSG_INTL(MSG_MAP_NOBADFRM)); 518 return (S_ERROR); 519 } 520 521 switch (*Start_tok) { 522 case 'l': 523 if (b_len) { 524 eprintf(ofl->ofl_lml, ERR_FATAL, 525 MSG_INTL(MSG_MAP_MOREONCE), 526 mapfile, EC_XWORD(Line_num), 527 MSG_INTL(MSG_MAP_SEGLEN)); 528 return (S_ERROR); 529 } 530 if ((sgp->sg_flags & FLG_SG_LENGTH) && 531 (sgp->sg_length != number)) 532 eprintf(ofl->ofl_lml, ERR_WARNING, 533 MSG_INTL(MSG_MAP_REDEFATT), 534 mapfile, EC_XWORD(Line_num), 535 MSG_INTL(MSG_MAP_SEGLEN), 536 sgp->sg_name); 537 sgp->sg_length = number; 538 sgp->sg_flags |= FLG_SG_LENGTH; 539 b_len = TRUE; 540 break; 541 case 'r': 542 if (b_round) { 543 eprintf(ofl->ofl_lml, ERR_FATAL, 544 MSG_INTL(MSG_MAP_MOREONCE), 545 mapfile, EC_XWORD(Line_num), 546 MSG_INTL(MSG_MAP_SEGROUND)); 547 return (S_ERROR); 548 } 549 if ((sgp->sg_flags & FLG_SG_ROUND) && 550 (sgp->sg_round != number)) 551 eprintf(ofl->ofl_lml, ERR_WARNING, 552 MSG_INTL(MSG_MAP_REDEFATT), 553 mapfile, EC_XWORD(Line_num), 554 MSG_INTL(MSG_MAP_SEGROUND), 555 sgp->sg_name); 556 sgp->sg_round = number; 557 sgp->sg_flags |= FLG_SG_ROUND; 558 b_round = TRUE; 559 break; 560 case 'v': 561 if (b_vaddr) { 562 eprintf(ofl->ofl_lml, ERR_FATAL, 563 MSG_INTL(MSG_MAP_MOREONCE), 564 mapfile, EC_XWORD(Line_num), 565 MSG_INTL(MSG_MAP_SEGVADDR)); 566 return (S_ERROR); 567 } 568 if ((sgp->sg_flags & FLG_SG_VADDR) && 569 (sgp->sg_phdr.p_vaddr != number)) 570 eprintf(ofl->ofl_lml, ERR_WARNING, 571 MSG_INTL(MSG_MAP_REDEFATT), 572 mapfile, EC_XWORD(Line_num), 573 MSG_INTL(MSG_MAP_SEGVADDR), 574 sgp->sg_name); 575 /* LINTED */ 576 sgp->sg_phdr.p_vaddr = (Addr)number; 577 sgp->sg_flags |= FLG_SG_VADDR; 578 ofl->ofl_flags1 |= FLG_OF1_VADDR; 579 b_vaddr = TRUE; 580 break; 581 case 'p': 582 if (b_paddr) { 583 eprintf(ofl->ofl_lml, ERR_FATAL, 584 MSG_INTL(MSG_MAP_MOREONCE), 585 mapfile, EC_XWORD(Line_num), 586 MSG_INTL(MSG_MAP_SEGPHYS)); 587 return (S_ERROR); 588 } 589 if ((sgp->sg_flags & FLG_SG_PADDR) && 590 (sgp->sg_phdr.p_paddr != number)) 591 eprintf(ofl->ofl_lml, ERR_WARNING, 592 MSG_INTL(MSG_MAP_REDEFATT), 593 mapfile, EC_XWORD(Line_num), 594 MSG_INTL(MSG_MAP_SEGPHYS), 595 sgp->sg_name); 596 /* LINTED */ 597 sgp->sg_phdr.p_paddr = (Addr)number; 598 sgp->sg_flags |= FLG_SG_PADDR; 599 b_paddr = TRUE; 600 break; 601 case 'a': 602 if (b_align) { 603 eprintf(ofl->ofl_lml, ERR_FATAL, 604 MSG_INTL(MSG_MAP_MOREONCE), 605 mapfile, EC_XWORD(Line_num), 606 MSG_INTL(MSG_MAP_SEGALIGN)); 607 return (S_ERROR); 608 } 609 if ((sgp->sg_flags & FLG_SG_ALIGN) && 610 (sgp->sg_phdr.p_align != number)) 611 eprintf(ofl->ofl_lml, ERR_WARNING, 612 MSG_INTL(MSG_MAP_REDEFATT), 613 mapfile, EC_XWORD(Line_num), 614 MSG_INTL(MSG_MAP_SEGALIGN), 615 sgp->sg_name); 616 /* LINTED */ 617 sgp->sg_phdr.p_align = (Xword)number; 618 sgp->sg_flags |= FLG_SG_ALIGN; 619 b_align = TRUE; 620 break; 621 } 622 } else { 623 eprintf(ofl->ofl_lml, ERR_FATAL, 624 MSG_INTL(MSG_MAP_UNKSEGATT), mapfile, 625 EC_XWORD(Line_num), Start_tok); 626 return (S_ERROR); 627 } 628 } 629 630 /* 631 * Empty segments can be used to define PT_LOAD segment reservations, or 632 * to reserve PT_NULL program headers. 633 * 634 * PT_LOAD reservations are only allowed within executables, as the 635 * reservation must be established through exec() as part of initial 636 * process loading. In addition, PT_LOAD reservations must have an 637 * associated address and size. 638 * 639 * PT_NULL program headers are established for later use by applications 640 * such as the post-optimizer. PT_NULL headers should have no other 641 * attributes assigned. 642 */ 643 if ((sgp->sg_flags & FLG_SG_EMPTY) && 644 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 645 646 /* 647 * Any style of empty segment should have no permissions. 648 */ 649 if (sgp->sg_phdr.p_flags != 0) { 650 eprintf(ofl->ofl_lml, ERR_FATAL, 651 MSG_INTL(MSG_MAP_SEGEMNOPERM), mapfile, 652 EC_XWORD(Line_num), 653 EC_WORD(sgp->sg_phdr.p_flags)); 654 return (S_ERROR); 655 } 656 657 if (sgp->sg_phdr.p_type == PT_LOAD) { 658 if ((ofl->ofl_flags & FLG_OF_EXEC) == 0) { 659 eprintf(ofl->ofl_lml, ERR_FATAL, 660 MSG_INTL(MSG_MAP_SEGEMPEXE), mapfile, 661 EC_XWORD(Line_num)); 662 return (S_ERROR); 663 } 664 if ((sgp->sg_flags & (FLG_SG_LENGTH | FLG_SG_VADDR)) != 665 (FLG_SG_LENGTH | FLG_SG_VADDR)) { 666 eprintf(ofl->ofl_lml, ERR_FATAL, 667 MSG_INTL(MSG_MAP_SEGEMPATT), mapfile, 668 EC_XWORD(Line_num)); 669 return (S_ERROR); 670 } 671 } else if (sgp->sg_phdr.p_type == PT_NULL) { 672 if ((sgp->sg_flags & (FLG_SG_LENGTH | FLG_SG_VADDR)) && 673 ((sgp->sg_length != 0) || 674 (sgp->sg_phdr.p_vaddr != 0))) { 675 eprintf(ofl->ofl_lml, ERR_FATAL, 676 MSG_INTL(MSG_MAP_SEGEMPNOATT), mapfile, 677 EC_XWORD(Line_num)); 678 return (S_ERROR); 679 } 680 } else { 681 eprintf(ofl->ofl_lml, ERR_WARNING, 682 MSG_INTL(MSG_MAP_SEGEMPLOAD), mapfile, 683 EC_XWORD(Line_num)); 684 sgp->sg_phdr.p_type = PT_LOAD; 685 } 686 } 687 688 /* 689 * All segment attributes have now been scanned. Certain flags do not 690 * make sense if this is not a loadable segment, fix if necessary. 691 * Note, if the segment is of type PT_NULL it must be new, and any 692 * defaults will be applied back in ld_map_parse(). 693 * When clearing an attribute leave the flag set as an indicator for 694 * later entries re-specifying the same segment. 695 */ 696 if ((sgp->sg_phdr.p_type != PT_NULL) && 697 (sgp->sg_phdr.p_type != PT_LOAD)) { 698 const char *fmt; 699 700 if (sgp->sg_phdr.p_type == PT_SUNWSTACK) 701 fmt = MSG_INTL(MSG_MAP_NOSTACK1); 702 else 703 fmt = MSG_INTL(MSG_MAP_NONLOAD); 704 705 if ((sgp->sg_flags & FLG_SG_FLAGS) && 706 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 707 if (sgp->sg_phdr.p_flags != 0) { 708 eprintf(ofl->ofl_lml, ERR_WARNING, 709 MSG_INTL(MSG_MAP_NONLOAD), mapfile, 710 EC_XWORD(Line_num), 711 MSG_INTL(MSG_MAP_SEGFLAG)); 712 sgp->sg_phdr.p_flags = 0; 713 } 714 } 715 if (sgp->sg_flags & FLG_SG_LENGTH) 716 if (sgp->sg_length != 0) { 717 eprintf(ofl->ofl_lml, ERR_WARNING, 718 fmt, mapfile, EC_XWORD(Line_num), 719 MSG_INTL(MSG_MAP_SEGLEN)); 720 sgp->sg_length = 0; 721 } 722 if (sgp->sg_flags & FLG_SG_ROUND) 723 if (sgp->sg_round != 0) { 724 eprintf(ofl->ofl_lml, ERR_WARNING, 725 fmt, mapfile, EC_XWORD(Line_num), 726 MSG_INTL(MSG_MAP_SEGROUND)); 727 sgp->sg_round = 0; 728 } 729 if (sgp->sg_flags & FLG_SG_VADDR) { 730 if (sgp->sg_phdr.p_vaddr != 0) { 731 eprintf(ofl->ofl_lml, ERR_WARNING, 732 fmt, mapfile, EC_XWORD(Line_num), 733 MSG_INTL(MSG_MAP_SEGVADDR)); 734 sgp->sg_phdr.p_vaddr = 0; 735 } 736 } 737 if (sgp->sg_flags & FLG_SG_PADDR) 738 if (sgp->sg_phdr.p_paddr != 0) { 739 eprintf(ofl->ofl_lml, ERR_WARNING, 740 fmt, mapfile, EC_XWORD(Line_num), 741 MSG_INTL(MSG_MAP_SEGPHYS)); 742 sgp->sg_phdr.p_paddr = 0; 743 } 744 if (sgp->sg_flags & FLG_SG_ALIGN) 745 if (sgp->sg_phdr.p_align != 0) { 746 eprintf(ofl->ofl_lml, ERR_WARNING, 747 fmt, mapfile, EC_XWORD(Line_num), 748 MSG_INTL(MSG_MAP_SEGALIGN)); 749 sgp->sg_phdr.p_align = 0; 750 } 751 } 752 return (1); 753 } 754 755 756 /* 757 * Process a mapfile mapping directives definition. 758 * segment_name : section_attribute [ : file_name ] 759 * segment_attribute : section_name section_type section_flags; 760 */ 761 static uintptr_t 762 map_colon(Ofl_desc *ofl, const char *mapfile, Ent_desc *enp) 763 { 764 Token tok; /* Current token. */ 765 766 Boolean b_name = FALSE; 767 Boolean b_type = FALSE; 768 Boolean b_attr = FALSE; 769 Boolean b_bang = FALSE; 770 static Xword index = 0; 771 772 773 while (((tok = gettoken(ofl, mapfile)) != TK_COLON) && 774 (tok != TK_SEMICOLON)) { 775 /* LINTED */ 776 if (tok == (Token)S_ERROR) 777 return (S_ERROR); 778 if (tok == TK_EOF) { 779 eprintf(ofl->ofl_lml, ERR_FATAL, 780 MSG_INTL(MSG_MAP_PREMEOF), mapfile, 781 EC_XWORD(Line_num)); 782 return (S_ERROR); 783 } 784 785 /* Segment type. */ 786 787 if (*Start_tok == '$') { 788 if (b_type) { 789 eprintf(ofl->ofl_lml, ERR_FATAL, 790 MSG_INTL(MSG_MAP_MOREONCE), mapfile, 791 EC_XWORD(Line_num), 792 MSG_INTL(MSG_MAP_SECTYP)); 793 return (S_ERROR); 794 } 795 b_type = TRUE; 796 Start_tok++; 797 lowercase(Start_tok); 798 if (strcmp(Start_tok, MSG_ORIG(MSG_STR_PROGBITS)) == 0) 799 enp->ec_type = SHT_PROGBITS; 800 else if (strcmp(Start_tok, 801 MSG_ORIG(MSG_STR_SYMTAB)) == 0) 802 enp->ec_type = SHT_SYMTAB; 803 else if (strcmp(Start_tok, 804 MSG_ORIG(MSG_STR_DYNSYM)) == 0) 805 enp->ec_type = SHT_DYNSYM; 806 else if (strcmp(Start_tok, 807 MSG_ORIG(MSG_STR_STRTAB)) == 0) 808 enp->ec_type = SHT_STRTAB; 809 else if ((strcmp(Start_tok, 810 MSG_ORIG(MSG_STR_REL)) == 0) || 811 (strcmp(Start_tok, MSG_ORIG(MSG_STR_RELA)) == 0)) 812 enp->ec_type = ld_targ.t_m.m_rel_sht_type; 813 else if (strcmp(Start_tok, MSG_ORIG(MSG_STR_HASH)) == 0) 814 enp->ec_type = SHT_HASH; 815 else if (strcmp(Start_tok, MSG_ORIG(MSG_STR_LIB)) == 0) 816 enp->ec_type = SHT_SHLIB; 817 else if (strcmp(Start_tok, 818 MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) 819 enp->ec_type = SHT_DYNAMIC; 820 else if (strcmp(Start_tok, MSG_ORIG(MSG_STR_NOTE)) == 0) 821 enp->ec_type = SHT_NOTE; 822 else if (strcmp(Start_tok, 823 MSG_ORIG(MSG_STR_NOBITS)) == 0) 824 enp->ec_type = SHT_NOBITS; 825 else { 826 eprintf(ofl->ofl_lml, ERR_FATAL, 827 MSG_INTL(MSG_MAP_UNKSECTYP), mapfile, 828 EC_XWORD(Line_num), Start_tok); 829 return (S_ERROR); 830 } 831 832 /* 833 * Segment flags. 834 * If a segment flag is specified then the appropriate bit is 835 * set in the ec_attrmask, the ec_attrbits fields determine 836 * whether the attrmask fields must be tested true or false 837 * ie. for ?A the attrmask is set and the attrbit is set, 838 * for ?!A the attrmask is set and the attrbit is clear. 839 */ 840 } else if (*Start_tok == '?') { 841 if (b_attr) { 842 eprintf(ofl->ofl_lml, ERR_FATAL, 843 MSG_INTL(MSG_MAP_MOREONCE), mapfile, 844 EC_XWORD(Line_num), 845 MSG_INTL(MSG_MAP_SECFLAG)); 846 return (S_ERROR); 847 } 848 b_attr = TRUE; 849 b_bang = FALSE; 850 Start_tok++; 851 lowercase(Start_tok); 852 for (; *Start_tok != '\0'; Start_tok++) 853 switch (*Start_tok) { 854 case '!': 855 if (b_bang) { 856 eprintf(ofl->ofl_lml, ERR_FATAL, 857 MSG_INTL(MSG_MAP_BADFLAG), 858 mapfile, EC_XWORD(Line_num), 859 Start_tok); 860 return (S_ERROR); 861 } 862 b_bang = TRUE; 863 break; 864 case 'a': 865 if (enp->ec_attrmask & SHF_ALLOC) { 866 eprintf(ofl->ofl_lml, ERR_FATAL, 867 MSG_INTL(MSG_MAP_BADFLAG), 868 mapfile, EC_XWORD(Line_num), 869 Start_tok); 870 return (S_ERROR); 871 } 872 enp->ec_attrmask |= SHF_ALLOC; 873 if (!b_bang) 874 enp->ec_attrbits |= SHF_ALLOC; 875 b_bang = FALSE; 876 break; 877 case 'w': 878 if (enp->ec_attrmask & SHF_WRITE) { 879 eprintf(ofl->ofl_lml, ERR_FATAL, 880 MSG_INTL(MSG_MAP_BADFLAG), 881 mapfile, EC_XWORD(Line_num), 882 Start_tok); 883 return (S_ERROR); 884 } 885 enp->ec_attrmask |= SHF_WRITE; 886 if (!b_bang) 887 enp->ec_attrbits |= SHF_WRITE; 888 b_bang = FALSE; 889 break; 890 case 'x': 891 if (enp->ec_attrmask & SHF_EXECINSTR) { 892 eprintf(ofl->ofl_lml, ERR_FATAL, 893 MSG_INTL(MSG_MAP_BADFLAG), 894 mapfile, EC_XWORD(Line_num), 895 Start_tok); 896 return (S_ERROR); 897 } 898 enp->ec_attrmask |= SHF_EXECINSTR; 899 if (!b_bang) 900 enp->ec_attrbits |= 901 SHF_EXECINSTR; 902 b_bang = FALSE; 903 break; 904 default: 905 eprintf(ofl->ofl_lml, ERR_FATAL, 906 MSG_INTL(MSG_MAP_BADFLAG), 907 mapfile, EC_XWORD(Line_num), 908 Start_tok); 909 return (S_ERROR); 910 } 911 /* 912 * Section name. 913 */ 914 } else { 915 if (b_name) { 916 eprintf(ofl->ofl_lml, ERR_FATAL, 917 MSG_INTL(MSG_MAP_MOREONCE), mapfile, 918 EC_XWORD(Line_num), 919 MSG_INTL(MSG_MAP_SECNAME)); 920 return (S_ERROR); 921 } 922 b_name = TRUE; 923 if ((enp->ec_name = 924 libld_malloc(strlen(Start_tok) + 1)) == 0) 925 return (S_ERROR); 926 (void) strcpy((char *)enp->ec_name, Start_tok); 927 /* 928 * get the index for text reordering 929 */ 930 /* LINTED */ 931 enp->ec_ndx = (Word)++index; 932 } 933 } 934 if (tok == TK_COLON) { 935 /* 936 * File names. 937 */ 938 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 939 char *file; 940 941 /* LINTED */ 942 if (tok == (Token)S_ERROR) 943 return (S_ERROR); 944 if (tok == TK_EOF) { 945 eprintf(ofl->ofl_lml, ERR_FATAL, 946 MSG_INTL(MSG_MAP_PREMEOF), mapfile, 947 EC_XWORD(Line_num)); 948 return (S_ERROR); 949 } 950 if (tok != TK_STRING) { 951 eprintf(ofl->ofl_lml, ERR_FATAL, 952 MSG_INTL(MSG_MAP_MALFORM), mapfile, 953 EC_XWORD(Line_num)); 954 return (S_ERROR); 955 } 956 if ((file = 957 libld_malloc(strlen(Start_tok) + 1)) == 0) 958 return (S_ERROR); 959 (void) strcpy(file, Start_tok); 960 if (list_appendc(&(enp->ec_files), file) == 0) 961 return (S_ERROR); 962 } 963 } 964 return (1); 965 } 966 967 /* 968 * Obtain a pseudo input file descriptor to assign to a mapfile. This is 969 * required any time a symbol is generated. First traverse the input file 970 * descriptors looking for a match. As all mapfile processing occurs before 971 * any real input file processing this list is going to be small and we don't 972 * need to do any filename clash checking. 973 */ 974 static Ifl_desc * 975 map_ifl(const char *mapfile, Ofl_desc *ofl) 976 { 977 Ifl_desc *ifl; 978 Listnode *lnp; 979 980 for (LIST_TRAVERSE(&ofl->ofl_objs, lnp, ifl)) 981 if (strcmp(ifl->ifl_name, mapfile) == 0) 982 return (ifl); 983 984 if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == 0) 985 return ((Ifl_desc *)S_ERROR); 986 ifl->ifl_name = mapfile; 987 ifl->ifl_flags = (FLG_IF_MAPFILE | FLG_IF_NEEDED | FLG_IF_FILEREF); 988 if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 1)) == 0) 989 return ((Ifl_desc *)S_ERROR); 990 ifl->ifl_ehdr->e_type = ET_REL; 991 992 if (list_appendc(&ofl->ofl_objs, ifl) == 0) 993 return ((Ifl_desc *)S_ERROR); 994 else 995 return (ifl); 996 } 997 998 /* 999 * Process a mapfile size symbol definition. 1000 * segment_name @ symbol_name; 1001 */ 1002 static uintptr_t 1003 map_atsign(const char *mapfile, Sg_desc *sgp, Ofl_desc *ofl) 1004 { 1005 Sym *sym; /* New symbol pointer */ 1006 Sym_desc *sdp; /* New symbol node pointer */ 1007 Ifl_desc *ifl; /* Dummy input file structure */ 1008 Token tok; /* Current token. */ 1009 avl_index_t where; 1010 1011 if ((tok = gettoken(ofl, mapfile)) != TK_STRING) { 1012 /* LINTED */ 1013 if (tok != (Token)S_ERROR) 1014 eprintf(ofl->ofl_lml, ERR_FATAL, 1015 MSG_INTL(MSG_MAP_EXPSYM_1), mapfile, 1016 EC_XWORD(Line_num)); 1017 return (S_ERROR); 1018 } 1019 1020 if (sgp->sg_sizesym != NULL) { 1021 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_MAP_SEGSIZE), 1022 mapfile, EC_XWORD(Line_num), sgp->sg_name); 1023 return (S_ERROR); 1024 } 1025 1026 /* 1027 * Make sure we have a pseudo file descriptor to associate to the 1028 * symbol. 1029 */ 1030 if ((ifl = map_ifl(mapfile, ofl)) == (Ifl_desc *)S_ERROR) 1031 return (S_ERROR); 1032 1033 /* 1034 * Make sure the symbol doesn't already exist. It is possible that the 1035 * symbol has been scoped or versioned, in which case it does exist 1036 * but we can freely update it here. 1037 */ 1038 if ((sdp = ld_sym_find(Start_tok, SYM_NOHASH, &where, ofl)) == NULL) { 1039 char *name; 1040 Word hval; 1041 1042 if ((name = libld_malloc(strlen(Start_tok) + 1)) == 0) 1043 return (S_ERROR); 1044 (void) strcpy(name, Start_tok); 1045 1046 if ((sym = libld_calloc(sizeof (Sym), 1)) == 0) 1047 return (S_ERROR); 1048 sym->st_shndx = SHN_ABS; 1049 sym->st_size = 0; 1050 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 1051 1052 DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, name)); 1053 /* LINTED */ 1054 hval = (Word)elf_hash(name); 1055 if ((sdp = ld_sym_enter(name, sym, hval, ifl, ofl, 0, SHN_ABS, 1056 (FLG_SY_SPECSEC | FLG_SY_GLOBREF), 0, &where)) == 1057 (Sym_desc *)S_ERROR) 1058 return (S_ERROR); 1059 sdp->sd_flags &= ~FLG_SY_CLEAN; 1060 DBG_CALL(Dbg_map_symbol(ofl, sdp)); 1061 } else { 1062 sym = sdp->sd_sym; 1063 1064 if (sym->st_shndx == SHN_UNDEF) { 1065 sdp->sd_shndx = sym->st_shndx = SHN_ABS; 1066 sdp->sd_flags |= FLG_SY_SPECSEC; 1067 sym->st_size = 0; 1068 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT); 1069 1070 sdp->sd_flags &= ~FLG_SY_MAPREF; 1071 1072 DBG_CALL(Dbg_map_size_old(ofl, sdp)); 1073 } else { 1074 eprintf(ofl->ofl_lml, ERR_FATAL, 1075 MSG_INTL(MSG_MAP_SYMDEF1), mapfile, 1076 EC_XWORD(Line_num), demangle(sdp->sd_name), 1077 sdp->sd_file->ifl_name, 1078 MSG_INTL(MSG_MAP_DIFF_SYMMUL)); 1079 return (S_ERROR); 1080 } 1081 } 1082 1083 /* 1084 * Assign the symbol to the segment. 1085 */ 1086 sgp->sg_sizesym = sdp; 1087 1088 if (gettoken(ofl, mapfile) != TK_SEMICOLON) { 1089 /* LINTED */ 1090 if (tok != (Token)S_ERROR) 1091 eprintf(ofl->ofl_lml, ERR_FATAL, 1092 MSG_INTL(MSG_MAP_EXPSCOL), mapfile, 1093 EC_XWORD(Line_num)); 1094 return (S_ERROR); 1095 } else 1096 return (1); 1097 } 1098 1099 1100 static uintptr_t 1101 map_pipe(Ofl_desc *ofl, const char *mapfile, Sg_desc *sgp) 1102 { 1103 char *sec_name; /* section name */ 1104 Token tok; /* current token. */ 1105 Sec_order *sc_order; 1106 static Word index = 0; /* used to maintain a increasing */ 1107 /* index for section ordering. */ 1108 1109 if ((tok = gettoken(ofl, mapfile)) != TK_STRING) { 1110 /* LINTED */ 1111 if (tok != (Token)S_ERROR) 1112 eprintf(ofl->ofl_lml, ERR_FATAL, 1113 MSG_INTL(MSG_MAP_EXPSEC), mapfile, 1114 EC_XWORD(Line_num)); 1115 return (S_ERROR); 1116 } 1117 1118 if ((sec_name = libld_malloc(strlen(Start_tok) + 1)) == 0) 1119 return (S_ERROR); 1120 (void) strcpy(sec_name, Start_tok); 1121 1122 if ((sc_order = libld_malloc(sizeof (Sec_order))) == 0) 1123 return (S_ERROR); 1124 1125 sc_order->sco_secname = sec_name; 1126 sc_order->sco_index = ++index; 1127 1128 if (aplist_append(&sgp->sg_secorder, sc_order, 1129 AL_CNT_SG_SECORDER) == NULL) 1130 return (S_ERROR); 1131 1132 DBG_CALL(Dbg_map_pipe(ofl->ofl_lml, sgp, sec_name, index)); 1133 1134 if ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 1135 /* LINTED */ 1136 if (tok != (Token)S_ERROR) 1137 eprintf(ofl->ofl_lml, ERR_FATAL, 1138 MSG_INTL(MSG_MAP_EXPSCOL), mapfile, 1139 EC_XWORD(Line_num)); 1140 return (S_ERROR); 1141 } 1142 1143 return (1); 1144 } 1145 1146 1147 /* 1148 * Process a mapfile library specification definition. 1149 * shared_object_name - shared object definition 1150 * shared object definition : [ shared object type [ = SONAME ]] 1151 * [ versions ]; 1152 */ 1153 static uintptr_t 1154 map_dash(const char *mapfile, char *name, Ofl_desc *ofl) 1155 { 1156 char *version; 1157 Token tok; 1158 Sdf_desc *sdf; 1159 Sdv_desc *sdv; 1160 enum { 1161 MD_NONE = 0, 1162 MD_SPECVERS, 1163 MD_ADDVERS, 1164 MD_NEEDED 1165 } dolkey = MD_NONE; 1166 1167 1168 /* 1169 * If a shared object definition for this file already exists use it, 1170 * otherwise allocate a new descriptor. 1171 */ 1172 if ((sdf = sdf_find(name, &ofl->ofl_socntl)) == 0) { 1173 if ((sdf = sdf_add(name, &ofl->ofl_socntl)) == 1174 (Sdf_desc *)S_ERROR) 1175 return (S_ERROR); 1176 sdf->sdf_rfile = mapfile; 1177 } 1178 1179 /* 1180 * Get the shared object descriptor string. 1181 */ 1182 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 1183 /* LINTED */ 1184 if (tok == (Token)S_ERROR) 1185 return (S_ERROR); 1186 if (tok == TK_EOF) { 1187 eprintf(ofl->ofl_lml, ERR_FATAL, 1188 MSG_INTL(MSG_MAP_PREMEOF), mapfile, 1189 EC_XWORD(Line_num)); 1190 return (S_ERROR); 1191 } 1192 if ((tok != TK_STRING) && (tok != TK_EQUAL)) { 1193 eprintf(ofl->ofl_lml, ERR_FATAL, 1194 MSG_INTL(MSG_MAP_EXPSO), mapfile, 1195 EC_XWORD(Line_num)); 1196 return (S_ERROR); 1197 } 1198 1199 /* 1200 * Determine if the library type is accompanied with a SONAME 1201 * definition. 1202 */ 1203 if (tok == TK_EQUAL) { 1204 if ((tok = gettoken(ofl, mapfile)) != TK_STRING) { 1205 /* LINTED */ 1206 if (tok == (Token)S_ERROR) 1207 return (S_ERROR); 1208 else { 1209 eprintf(ofl->ofl_lml, ERR_FATAL, 1210 MSG_INTL(MSG_MAP_EXPSO), mapfile, 1211 EC_XWORD(Line_num)); 1212 return (S_ERROR); 1213 } 1214 } 1215 switch (dolkey) { 1216 case MD_NEEDED: 1217 if (sdf->sdf_flags & FLG_SDF_SONAME) { 1218 eprintf(ofl->ofl_lml, ERR_WARNING, 1219 MSG_INTL(MSG_MAP_MULSONAME), 1220 mapfile, EC_XWORD(Line_num), name, 1221 sdf->sdf_soname, Start_tok); 1222 dolkey = MD_NONE; 1223 continue; 1224 } 1225 if ((sdf->sdf_soname = 1226 libld_malloc(strlen(Start_tok) + 1)) == 0) 1227 return (S_ERROR); 1228 (void) strcpy((char *)sdf->sdf_soname, 1229 Start_tok); 1230 sdf->sdf_flags |= FLG_SDF_SONAME; 1231 break; 1232 case MD_SPECVERS: 1233 case MD_ADDVERS: 1234 if ((sdv = libld_calloc( 1235 sizeof (Sdv_desc), 1)) == 0) 1236 return (S_ERROR); 1237 1238 if (dolkey == MD_SPECVERS) 1239 sdf->sdf_flags |= FLG_SDF_SPECVER; 1240 else 1241 sdf->sdf_flags |= FLG_SDF_ADDVER; 1242 1243 if ((sdf->sdf_flags & (FLG_SDF_SPECVER | 1244 FLG_SDF_ADDVER)) == (FLG_SDF_SPECVER | 1245 FLG_SDF_ADDVER)) { 1246 eprintf(ofl->ofl_lml, ERR_FATAL, 1247 MSG_INTL(MSG_MAP_INCOMFLG), 1248 mapfile, EC_XWORD(Line_num), 1249 sdf->sdf_name); 1250 return (S_ERROR); 1251 } 1252 if ((version = 1253 libld_malloc(strlen(Start_tok) + 1)) == 0) 1254 return (S_ERROR); 1255 (void) strcpy(version, Start_tok); 1256 sdv->sdv_name = version; 1257 sdv->sdv_ref = mapfile; 1258 if (list_appendc(&sdf->sdf_verneed, sdv) == 0) 1259 return (S_ERROR); 1260 break; 1261 case MD_NONE: 1262 eprintf(ofl->ofl_lml, ERR_FATAL, 1263 MSG_INTL(MSG_MAP_UNEXTOK), mapfile, 1264 EC_XWORD(Line_num), '='); 1265 return (S_ERROR); 1266 } 1267 dolkey = MD_NONE; 1268 continue; 1269 } 1270 1271 /* 1272 * A shared object type has been specified. This may also be 1273 * accompanied by an SONAME redefinition (see above). 1274 */ 1275 if (*Start_tok == '$') { 1276 if (dolkey != MD_NONE) { 1277 eprintf(ofl->ofl_lml, ERR_FATAL, 1278 MSG_INTL(MSG_MAP_UNEXTOK), mapfile, 1279 EC_XWORD(Line_num), '$'); 1280 return (S_ERROR); 1281 } 1282 Start_tok++; 1283 lowercase(Start_tok); 1284 if (strcmp(Start_tok, 1285 MSG_ORIG(MSG_MAP_NEED)) == 0) 1286 dolkey = MD_NEEDED; 1287 else if (strcmp(Start_tok, 1288 MSG_ORIG(MSG_MAP_SPECVERS)) == 0) 1289 dolkey = MD_SPECVERS; 1290 else if (strcmp(Start_tok, 1291 MSG_ORIG(MSG_MAP_ADDVERS)) == 0) 1292 dolkey = MD_ADDVERS; 1293 else { 1294 eprintf(ofl->ofl_lml, ERR_FATAL, 1295 MSG_INTL(MSG_MAP_UNKSOTYP), mapfile, 1296 EC_XWORD(Line_num), Start_tok); 1297 return (S_ERROR); 1298 } 1299 continue; 1300 } 1301 1302 /* 1303 * shared object version requirement. 1304 */ 1305 if ((version = libld_malloc(strlen(Start_tok) + 1)) == 0) 1306 return (S_ERROR); 1307 (void) strcpy(version, Start_tok); 1308 if ((sdv = libld_calloc(sizeof (Sdv_desc), 1)) == 0) 1309 return (S_ERROR); 1310 sdv->sdv_name = version; 1311 sdv->sdv_ref = mapfile; 1312 sdf->sdf_flags |= FLG_SDF_SELECT; 1313 if (list_appendc(&sdf->sdf_vers, sdv) == 0) 1314 return (S_ERROR); 1315 } 1316 1317 DBG_CALL(Dbg_map_dash(ofl->ofl_lml, name, sdf)); 1318 return (1); 1319 } 1320 1321 1322 /* 1323 * Process a symbol definition. Historically, this originated from processing 1324 * a version definition. However, this has evolved into a generic means of 1325 * defining symbol references and definitions (see Defining Additional Symbols 1326 * in the Linker and Libraries guide for the complete syntax). 1327 * 1328 * [ name ] { 1329 * scope: 1330 * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ]; 1331 * } [ dependency ]; 1332 * 1333 */ 1334 #define FLG_SCOPE_HIDD 0 /* symbol defined hidden/local */ 1335 #define FLG_SCOPE_DFLT 1 /* symbol defined default/global */ 1336 #define FLG_SCOPE_PROT 2 /* symbol defined protected/symbolic */ 1337 #define FLG_SCOPE_EXPT 3 /* symbol defined exported */ 1338 #define FLG_SCOPE_SNGL 4 /* symbol defined singleton */ 1339 #define FLG_SCOPE_ELIM 5 /* symbol defined eliminate */ 1340 1341 static uintptr_t 1342 map_version(const char *mapfile, char *name, Ofl_desc *ofl) 1343 { 1344 Token tok; 1345 Sym *sym; 1346 int scope = FLG_SCOPE_DFLT, errcnt = 0; 1347 Ver_desc *vdp; 1348 Word hash; 1349 Ifl_desc *ifl; 1350 avl_index_t where; 1351 1352 /* 1353 * If we're generating segments within the image then any symbol 1354 * reductions will be processed (ie. applied to relocations and symbol 1355 * table entries). Otherwise (when creating a relocatable object) any 1356 * versioning information is simply recorded for use in a later 1357 * (segment generating) link-edit. 1358 */ 1359 if (ofl->ofl_flags & FLG_OF_RELOBJ) 1360 ofl->ofl_flags |= FLG_OF_VERDEF; 1361 1362 /* 1363 * If this is a new mapfile reference generate an input file descriptor 1364 * to represent it. Otherwise this must simply be a new version within 1365 * the mapfile we've previously been processing, in this case continue 1366 * to use the original input file descriptor. 1367 */ 1368 if ((ifl = map_ifl(mapfile, ofl)) == (Ifl_desc *)S_ERROR) 1369 return (S_ERROR); 1370 1371 /* 1372 * If no version descriptors have yet been set up, initialize a base 1373 * version to represent the output file itself. This `base' version 1374 * catches any internally generated symbols (_end, _etext, etc.) and 1375 * serves to initialize the output version descriptor count. 1376 */ 1377 if (ofl->ofl_vercnt == 0) { 1378 if (ld_vers_base(ofl) == (Ver_desc *)S_ERROR) 1379 return (S_ERROR); 1380 } 1381 1382 /* 1383 * If this definition has an associated version name then generate a 1384 * new version descriptor and an associated version symbol index table. 1385 */ 1386 if (name) { 1387 ofl->ofl_flags |= FLG_OF_VERDEF; 1388 1389 /* 1390 * Traverse the present version descriptor list to see if there 1391 * is already one of the same name, otherwise create a new one. 1392 */ 1393 /* LINTED */ 1394 hash = (Word)elf_hash(name); 1395 if ((vdp = ld_vers_find(name, hash, &ofl->ofl_verdesc)) == 0) { 1396 if ((vdp = ld_vers_desc(name, hash, 1397 &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR) 1398 return (S_ERROR); 1399 } 1400 1401 /* 1402 * Initialize any new version with an index, the file from which 1403 * it was first referenced, and a WEAK flag (indicates that 1404 * there are no symbols assigned to it yet). 1405 */ 1406 if (vdp->vd_ndx == 0) { 1407 /* LINTED */ 1408 vdp->vd_ndx = (Half)++ofl->ofl_vercnt; 1409 vdp->vd_file = ifl; 1410 vdp->vd_flags = VER_FLG_WEAK; 1411 } 1412 } else { 1413 /* 1414 * If a version definition hasn't been specified assign any 1415 * symbols to the base version. 1416 */ 1417 vdp = (Ver_desc *)ofl->ofl_verdesc.head->data; 1418 } 1419 1420 /* 1421 * Scan the mapfile entry picking out scoping and symbol definitions. 1422 */ 1423 while ((tok = gettoken(ofl, mapfile)) != TK_RIGHTBKT) { 1424 Sym_desc * sdp; 1425 Word shndx = SHN_UNDEF; 1426 uchar_t type = STT_NOTYPE; 1427 Addr value = 0, size = 0; 1428 char *_name, *filtee = 0; 1429 Word sym_flags = 0; 1430 Half sym_flags1 = 0; 1431 uint_t filter = 0, novalue = 1, dftflag; 1432 const char *conflict; 1433 1434 if ((tok != TK_STRING) && (tok != TK_COLON)) { 1435 eprintf(ofl->ofl_lml, ERR_FATAL, 1436 MSG_INTL(MSG_MAP_EXPSYM_2), mapfile, 1437 EC_XWORD(Line_num)); 1438 errcnt++; 1439 continue; 1440 } 1441 1442 if ((_name = libld_malloc(strlen(Start_tok) + 1)) == 0) 1443 return (S_ERROR); 1444 (void) strcpy(_name, Start_tok); 1445 1446 if ((tok != TK_COLON) && 1447 /* LINTED */ 1448 (tok = gettoken(ofl, mapfile)) == (Token)S_ERROR) { 1449 errcnt++; 1450 continue; 1451 } 1452 1453 /* 1454 * Turn off the WEAK flag to indicate that definitions are 1455 * associated with this version. It would probably be more 1456 * accurate to only remove this flag with the specification of 1457 * global symbols, however setting it here allows enough slop 1458 * to compensate for the various user inputs we've seen so far. 1459 * Only if a closed version is specified (i.e., "SUNW_1.x {};") 1460 * will a user get a weak version (which is how we document the 1461 * creation of weak versions). 1462 */ 1463 vdp->vd_flags &= ~VER_FLG_WEAK; 1464 1465 switch (tok) { 1466 case TK_COLON: 1467 /* 1468 * Establish a new scope. All symbols added by this 1469 * mapfile are actually global entries, and are assigned 1470 * the scope that is presently in effect. 1471 * 1472 * If a protected/symbolic scope is detected, remember 1473 * this. If a protected/symbolic scope is the only 1474 * scope defined in this (or any other mapfiles), then 1475 * the mode -Bsymbolic is established. 1476 */ 1477 if ((strcmp(MSG_ORIG(MSG_MAP_DEFAULT), _name) == 0) || 1478 (strcmp(MSG_ORIG(MSG_MAP_GLOBAL), _name) == 0)) { 1479 scope = FLG_SCOPE_DFLT; 1480 ofl->ofl_flags |= FLG_OF_MAPGLOB; 1481 1482 } else if ((strcmp(MSG_ORIG(MSG_MAP_HIDDEN), 1483 _name) == 0) || 1484 (strcmp(MSG_ORIG(MSG_STR_LOCAL), _name) == 0)) { 1485 scope = FLG_SCOPE_HIDD; 1486 1487 } else if ((strcmp(MSG_ORIG(MSG_MAP_PROTECTED), 1488 _name) == 0) || 1489 (strcmp(MSG_ORIG(MSG_STR_SYMBOLIC), _name) == 0)) { 1490 scope = FLG_SCOPE_PROT; 1491 ofl->ofl_flags |= FLG_OF_MAPSYMB; 1492 1493 } else if (strcmp(MSG_ORIG(MSG_STR_EXPORTED), 1494 _name) == 0) { 1495 scope = FLG_SCOPE_EXPT; 1496 1497 } else if (strcmp(MSG_ORIG(MSG_STR_SINGLETON), 1498 _name) == 0) { 1499 scope = FLG_SCOPE_SNGL; 1500 ofl->ofl_flags |= FLG_OF_MAPGLOB; 1501 1502 } else if (strcmp(MSG_ORIG(MSG_STR_ELIMINATE), 1503 _name) == 0) { 1504 scope = FLG_SCOPE_ELIM; 1505 1506 } else { 1507 eprintf(ofl->ofl_lml, ERR_FATAL, 1508 MSG_INTL(MSG_MAP_UNKSYMSCO), mapfile, 1509 EC_XWORD(Line_num), _name); 1510 errcnt++; 1511 } 1512 continue; 1513 1514 case TK_EQUAL: 1515 /* 1516 * A full blown symbol definition follows. 1517 * Determine the symbol type and any virtual address or 1518 * alignment specified and then fall through to process 1519 * the entire symbols information. 1520 */ 1521 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 1522 /* 1523 * If we had previously seen a filter or 1524 * auxiliary filter requirement, the next string 1525 * is the filtee itself. 1526 */ 1527 if (filter) { 1528 if (filtee) { 1529 /* BEGIN CSTYLED */ 1530 eprintf(ofl->ofl_lml, ERR_FATAL, 1531 MSG_INTL(MSG_MAP_MULTFILTEE), 1532 mapfile, EC_XWORD(Line_num), 1533 _name); 1534 errcnt++; 1535 continue; 1536 /* END CSTYLED */ 1537 } 1538 if ((filtee = libld_malloc( 1539 strlen(Start_tok) + 1)) == 0) 1540 return (S_ERROR); 1541 (void) strcpy(filtee, Start_tok); 1542 filter = 0; 1543 continue; 1544 } 1545 1546 /* 1547 * Determine any Value or Size attributes. 1548 */ 1549 lowercase(Start_tok); 1550 1551 if (Start_tok[0] == 'v' || 1552 Start_tok[0] == 's') { 1553 char *end_tok; 1554 Lword number; 1555 1556 if ((number = (Lword)STRTOADDR( 1557 &Start_tok[1], &end_tok, 0)) == 1558 XWORD_MAX) { 1559 eprintf(ofl->ofl_lml, ERR_FATAL, 1560 MSG_INTL(MSG_MAP_SEGADDR), 1561 mapfile, EC_XWORD(Line_num), 1562 Start_tok, 1563 MSG_INTL(MSG_MAP_EXCLIMIT)); 1564 errcnt++; 1565 continue; 1566 } 1567 1568 if (end_tok != 1569 strchr(Start_tok, '\0')) { 1570 eprintf(ofl->ofl_lml, ERR_FATAL, 1571 MSG_INTL(MSG_MAP_SEGADDR), 1572 mapfile, EC_XWORD(Line_num), 1573 Start_tok, 1574 MSG_INTL(MSG_MAP_NOBADFRM)); 1575 errcnt++; 1576 continue; 1577 } 1578 1579 switch (*Start_tok) { 1580 case 'v': 1581 /* BEGIN CSTYLED */ 1582 if (value) { 1583 eprintf(ofl->ofl_lml, ERR_FATAL, 1584 MSG_INTL(MSG_MAP_MOREONCE), 1585 mapfile, EC_XWORD(Line_num), 1586 MSG_INTL(MSG_MAP_SYMVAL)); 1587 errcnt++; 1588 continue; 1589 } 1590 /* LINTED */ 1591 value = (Addr)number; 1592 novalue = 0; 1593 break; 1594 /* END CSTYLED */ 1595 case 's': 1596 /* BEGIN CSTYLED */ 1597 if (size) { 1598 eprintf(ofl->ofl_lml, ERR_FATAL, 1599 MSG_INTL(MSG_MAP_MOREONCE), 1600 mapfile, EC_XWORD(Line_num), 1601 MSG_INTL(MSG_MAP_SYMSIZE)); 1602 errcnt++; 1603 continue; 1604 } 1605 /* LINTED */ 1606 size = (Addr)number; 1607 break; 1608 /* END CSTYLED */ 1609 } 1610 1611 } else if (strcmp(Start_tok, 1612 MSG_ORIG(MSG_MAP_FUNCTION)) == 0) { 1613 shndx = SHN_ABS; 1614 sym_flags |= FLG_SY_SPECSEC; 1615 type = STT_FUNC; 1616 } else if (strcmp(Start_tok, 1617 MSG_ORIG(MSG_MAP_DATA)) == 0) { 1618 shndx = SHN_ABS; 1619 sym_flags |= FLG_SY_SPECSEC; 1620 type = STT_OBJECT; 1621 } else if (strcmp(Start_tok, 1622 MSG_ORIG(MSG_MAP_COMMON)) == 0) { 1623 shndx = SHN_COMMON; 1624 sym_flags |= FLG_SY_SPECSEC; 1625 type = STT_OBJECT; 1626 } else if (strcmp(Start_tok, 1627 MSG_ORIG(MSG_MAP_PARENT)) == 0) { 1628 sym_flags |= FLG_SY_PARENT; 1629 ofl->ofl_flags |= FLG_OF_SYMINFO; 1630 } else if (strcmp(Start_tok, 1631 MSG_ORIG(MSG_MAP_EXTERN)) == 0) { 1632 sym_flags |= FLG_SY_EXTERN; 1633 ofl->ofl_flags |= FLG_OF_SYMINFO; 1634 } else if (strcmp(Start_tok, 1635 MSG_ORIG(MSG_MAP_DIRECT)) == 0) { 1636 sym_flags1 |= FLG_SY1_DIR; 1637 ofl->ofl_flags |= FLG_OF_SYMINFO; 1638 } else if (strcmp(Start_tok, 1639 MSG_ORIG(MSG_MAP_NODIRECT)) == 0) { 1640 sym_flags1 |= FLG_SY1_NDIR; 1641 ofl->ofl_flags |= FLG_OF_SYMINFO; 1642 ofl->ofl_flags1 |= FLG_OF1_NDIRECT; 1643 } else if (strcmp(Start_tok, 1644 MSG_ORIG(MSG_MAP_FILTER)) == 0) { 1645 dftflag = filter = FLG_SY_STDFLTR; 1646 sym_flags |= FLG_SY_STDFLTR; 1647 ofl->ofl_flags |= FLG_OF_SYMINFO; 1648 continue; 1649 } else if (strcmp(Start_tok, 1650 MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) { 1651 dftflag = filter = FLG_SY_AUXFLTR; 1652 sym_flags |= FLG_SY_AUXFLTR; 1653 ofl->ofl_flags |= FLG_OF_SYMINFO; 1654 continue; 1655 } else if (strcmp(Start_tok, 1656 MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) { 1657 if (!(ofl->ofl_flags & FLG_OF_EXEC)) { 1658 eprintf(ofl->ofl_lml, ERR_FATAL, 1659 MSG_INTL(MSG_MAP_NOINTPOSE), 1660 mapfile, 1661 EC_XWORD(Line_num)); 1662 errcnt++; 1663 continue; 1664 } 1665 sym_flags |= FLG_SY_INTPOSE; 1666 ofl->ofl_flags |= FLG_OF_SYMINFO; 1667 ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE; 1668 continue; 1669 } else if (strcmp(Start_tok, 1670 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) { 1671 sym_flags |= FLG_SY_DYNSORT; 1672 sym_flags &= ~FLG_SY_NODYNSORT; 1673 continue; 1674 } else if (strcmp(Start_tok, 1675 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) { 1676 sym_flags &= ~FLG_SY_DYNSORT; 1677 sym_flags |= FLG_SY_NODYNSORT; 1678 continue; 1679 } else { 1680 eprintf(ofl->ofl_lml, ERR_FATAL, 1681 MSG_INTL(MSG_MAP_UNKSYMDEF), 1682 mapfile, EC_XWORD(Line_num), 1683 Start_tok); 1684 errcnt++; 1685 continue; 1686 } 1687 } 1688 /* FALLTHROUGH */ 1689 1690 case TK_SEMICOLON: 1691 /* 1692 * The special auto-reduction directive `*' can be 1693 * specified in hidden/local, and eliminate scope. This 1694 * directive indicates that all symbols processed that 1695 * are not explicitly defined to be global are to be 1696 * reduced to hidden/local scope in, or eliminated from, 1697 * the output image. 1698 * 1699 * An auto-reduction directive also implies that a 1700 * version definition be created, as the user has 1701 * effectively defined an interface. 1702 */ 1703 if (*_name == '*') { 1704 if (scope == FLG_SCOPE_HIDD) 1705 ofl->ofl_flags |= 1706 (FLG_OF_VERDEF | FLG_OF_AUTOLCL); 1707 else if (scope == FLG_SCOPE_ELIM) { 1708 ofl->ofl_flags |= 1709 (FLG_OF_VERDEF | FLG_OF_AUTOELM); 1710 } 1711 continue; 1712 } 1713 1714 /* 1715 * Add the new symbol. It should be noted that all 1716 * symbols added by the mapfile start out with global 1717 * scope, thus they will fall through the normal symbol 1718 * resolution process. Symbols defined as locals will 1719 * be reduced in scope after all input file processing. 1720 */ 1721 /* LINTED */ 1722 hash = (Word)elf_hash(_name); 1723 DBG_CALL(Dbg_map_version(ofl->ofl_lml, name, _name, 1724 scope)); 1725 if ((sdp = ld_sym_find(_name, hash, &where, 1726 ofl)) == NULL) { 1727 if ((sym = libld_calloc(sizeof (Sym), 1)) == 0) 1728 return (S_ERROR); 1729 1730 /* 1731 * Make sure any parent or external declarations 1732 * fall back to references. 1733 */ 1734 if (sym_flags & 1735 (FLG_SY_PARENT | FLG_SY_EXTERN)) { 1736 /* 1737 * Turn it into a reference by setting 1738 * the section index to UNDEF. 1739 */ 1740 sym->st_shndx = shndx = SHN_UNDEF; 1741 1742 /* 1743 * It is wrong to to specify size 1744 * or value for an external symbol. 1745 */ 1746 if ((novalue == 0) || (size != 0)) { 1747 eprintf(ofl->ofl_lml, ERR_FATAL, 1748 MSG_INTL(MSG_MAP_NOEXVLSZ), 1749 mapfile, 1750 EC_XWORD(Line_num)); 1751 errcnt++; 1752 continue; 1753 } 1754 } else { 1755 sym->st_shndx = (Half)shndx; 1756 } 1757 1758 sym->st_value = value; 1759 sym->st_size = size; 1760 sym->st_info = ELF_ST_INFO(STB_GLOBAL, type); 1761 1762 if ((sdp = ld_sym_enter(_name, sym, hash, ifl, 1763 ofl, 0, shndx, sym_flags, sym_flags1, 1764 &where)) == (Sym_desc *)S_ERROR) 1765 return (S_ERROR); 1766 1767 sdp->sd_flags &= ~FLG_SY_CLEAN; 1768 1769 /* 1770 * Identify any references. FLG_SY_MAPREF is 1771 * turned off once a relocatable object with 1772 * the same symbol is found, thus the existence 1773 * of FLG_SY_MAPREF at symbol validation is 1774 * used to flag undefined/misspelled entries. 1775 */ 1776 if (sym->st_shndx == SHN_UNDEF) 1777 sdp->sd_flags |= 1778 (FLG_SY_MAPREF | FLG_SY_GLOBREF); 1779 1780 } else { 1781 conflict = NULL; 1782 sym = sdp->sd_sym; 1783 1784 /* 1785 * If this symbol already exists, make sure this 1786 * definition doesn't conflict with the former. 1787 * Provided it doesn't, multiple definitions 1788 * from different mapfiles can augment each 1789 * other. 1790 */ 1791 /* BEGIN CSTYLED */ 1792 if (sym->st_value) { 1793 if (value && (sym->st_value != value)) 1794 conflict = 1795 MSG_INTL(MSG_MAP_DIFF_SYMVAL); 1796 } else { 1797 sym->st_value = value; 1798 } 1799 if (sym->st_size) { 1800 if (size && (sym->st_size != size)) 1801 conflict = MSG_INTL(MSG_MAP_DIFF_SYMSZ); 1802 } else { 1803 sym->st_size = size; 1804 } 1805 if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) { 1806 if ((type != STT_NOTYPE) && 1807 (ELF_ST_TYPE(sym->st_info) != type)) 1808 conflict = 1809 MSG_INTL(MSG_MAP_DIFF_SYMTYP); 1810 } else { 1811 sym->st_info = 1812 ELF_ST_INFO(STB_GLOBAL, type); 1813 } 1814 if (sym->st_shndx != SHN_UNDEF) { 1815 if ((shndx != SHN_UNDEF) && 1816 (sym->st_shndx != shndx)) 1817 conflict = 1818 MSG_INTL(MSG_MAP_DIFF_SYMNDX); 1819 } else { 1820 sdp->sd_shndx = sym->st_shndx = shndx; 1821 } 1822 /* END CSTYLED */ 1823 1824 if ((sdp->sd_flags1 & MSK_SY1_GLOBAL) && 1825 (sdp->sd_aux->sa_overndx != 1826 VER_NDX_GLOBAL) && 1827 (vdp->vd_ndx != VER_NDX_GLOBAL) && 1828 (sdp->sd_aux->sa_overndx != vdp->vd_ndx)) { 1829 conflict = 1830 MSG_INTL(MSG_MAP_DIFF_SYMVER); 1831 } 1832 1833 if (conflict) { 1834 eprintf(ofl->ofl_lml, ERR_FATAL, 1835 MSG_INTL(MSG_MAP_SYMDEF1), mapfile, 1836 EC_XWORD(Line_num), demangle(_name), 1837 sdp->sd_file->ifl_name, conflict); 1838 errcnt++; 1839 continue; 1840 } 1841 1842 /* 1843 * If this mapfile entry supplies a definition, 1844 * indicate that the symbol is now used. 1845 */ 1846 if (shndx != SHN_UNDEF) 1847 sdp->sd_flags |= FLG_SY_MAPUSED; 1848 } 1849 1850 /* 1851 * A symbol declaration that defines a size but no 1852 * value is processed as a request to create an 1853 * associated backing section. The intent behind this 1854 * functionality is to provide OBJT definitions within 1855 * filters that are not ABS. ABS symbols don't allow 1856 * copy-relocations to be established to filter OBJT 1857 * definitions. 1858 */ 1859 if ((shndx == SHN_ABS) && size && novalue && 1860 (sdp->sd_isc == 0)) { 1861 Is_desc *isp; 1862 1863 if (type == STT_OBJECT) { 1864 if ((isp = ld_make_data(ofl, 1865 size)) == (Is_desc *)S_ERROR) 1866 return (S_ERROR); 1867 } else { 1868 if ((isp = ld_make_text(ofl, 1869 size)) == (Is_desc *)S_ERROR) 1870 return (S_ERROR); 1871 } 1872 1873 /* 1874 * Now that backing storage has been created, 1875 * associate the symbol descriptor. Remove the 1876 * symbols special section tag so that it will 1877 * be assigned the correct section index as part 1878 * of update symbol processing. 1879 */ 1880 sdp->sd_flags &= ~FLG_SY_SPECSEC; 1881 sym_flags &= ~FLG_SY_SPECSEC; 1882 sdp->sd_isc = isp; 1883 isp->is_file = ifl; 1884 } 1885 1886 /* 1887 * Indicate the new symbols scope. Although the 1888 * symbols st_other field will eventually be updated as 1889 * part of writing out the final symbol, update the 1890 * st_other field here to trigger better diagnostics 1891 * during symbol validation (for example, undefined 1892 * references that are defined symbolic in a mapfile). 1893 */ 1894 if (scope == FLG_SCOPE_HIDD) { 1895 /* 1896 * This symbol needs to be reduced to local. 1897 */ 1898 if (ofl->ofl_flags & FLG_OF_REDLSYM) { 1899 sdp->sd_flags1 |= 1900 (FLG_SY1_HIDDEN | FLG_SY1_ELIM); 1901 sdp->sd_sym->st_other = STV_ELIMINATE; 1902 } else { 1903 sdp->sd_flags1 |= FLG_SY1_HIDDEN; 1904 sdp->sd_sym->st_other = STV_HIDDEN; 1905 } 1906 } else if (scope == FLG_SCOPE_ELIM) { 1907 /* 1908 * This symbol needs to be eliminated. Note, 1909 * the symbol is also tagged as local to trigger 1910 * any necessary relocation processing prior 1911 * to the symbol being eliminated. 1912 */ 1913 sdp->sd_flags1 |= 1914 (FLG_SY1_HIDDEN | FLG_SY1_ELIM); 1915 sdp->sd_sym->st_other = STV_ELIMINATE; 1916 1917 } else { 1918 /* 1919 * This symbol is explicitly defined to remain 1920 * global. 1921 */ 1922 sdp->sd_flags |= sym_flags; 1923 sdp->sd_flags1 |= sym_flags1; 1924 1925 /* 1926 * Qualify any global scope. 1927 */ 1928 if (scope == FLG_SCOPE_SNGL) { 1929 sdp->sd_flags1 |= 1930 (FLG_SY1_SINGLE | FLG_SY1_NDIR); 1931 sdp->sd_sym->st_other = STV_SINGLETON; 1932 } else if (scope == FLG_SCOPE_PROT) { 1933 sdp->sd_flags1 |= FLG_SY1_PROTECT; 1934 sdp->sd_sym->st_other = STV_PROTECTED; 1935 } else if (scope == FLG_SCOPE_EXPT) { 1936 sdp->sd_flags1 |= FLG_SY1_EXPORT; 1937 sdp->sd_sym->st_other = STV_EXPORTED; 1938 } else 1939 sdp->sd_flags1 |= FLG_SY1_DEFAULT; 1940 1941 /* 1942 * Record the present version index for later 1943 * potential versioning. 1944 */ 1945 if ((sdp->sd_aux->sa_overndx == 0) || 1946 (sdp->sd_aux->sa_overndx == VER_NDX_GLOBAL)) 1947 sdp->sd_aux->sa_overndx = vdp->vd_ndx; 1948 vdp->vd_flags |= FLG_VER_REFER; 1949 } 1950 1951 conflict = NULL; 1952 1953 /* 1954 * Carry out some validity checks to ensure incompatible 1955 * symbol characteristics have not been defined. 1956 * These checks are carried out after symbols are added 1957 * or resolved, to catch single instance, and 1958 * multi-instance definition inconsistencies. 1959 */ 1960 if ((sdp->sd_flags1 & 1961 (FLG_SY1_HIDDEN | FLG_SY1_ELIM)) && 1962 ((scope != FLG_SCOPE_HIDD) && 1963 (scope != FLG_SCOPE_ELIM))) { 1964 conflict = MSG_INTL(MSG_MAP_DIFF_SYMLCL); 1965 1966 } else if (((sdp->sd_flags1 & FLG_SY1_SINGLE) || 1967 (sdp->sd_flags1 & FLG_SY1_EXPORT)) && 1968 ((scope != FLG_SCOPE_DFLT) && 1969 (scope != FLG_SCOPE_EXPT) && 1970 (scope != FLG_SCOPE_SNGL))) { 1971 conflict = MSG_INTL(MSG_MAP_DIFF_SYMGLOB); 1972 1973 } else if ((sdp->sd_flags1 & FLG_SY1_PROTECT) && 1974 ((scope != FLG_SCOPE_DFLT) && 1975 (scope != FLG_SCOPE_PROT))) { 1976 conflict = MSG_INTL(MSG_MAP_DIFF_SYMPROT); 1977 1978 } else if ((sdp->sd_flags1 & FLG_SY1_NDIR) && 1979 (scope == FLG_SCOPE_PROT)) { 1980 conflict = MSG_INTL(MSG_MAP_DIFF_PROTNDIR); 1981 1982 } else if ((sdp->sd_flags1 & FLG_SY1_DIR) && 1983 (scope == FLG_SCOPE_SNGL)) { 1984 conflict = MSG_INTL(MSG_MAP_DIFF_SNGLDIR); 1985 } 1986 1987 if (conflict) { 1988 /* 1989 * Select the conflict message from either a 1990 * single instance or multi-instance definition. 1991 */ 1992 if (sdp->sd_file->ifl_name == mapfile) { 1993 eprintf(ofl->ofl_lml, ERR_FATAL, 1994 MSG_INTL(MSG_MAP_SYMDEF2), mapfile, 1995 EC_XWORD(Line_num), demangle(_name), 1996 conflict); 1997 } else { 1998 eprintf(ofl->ofl_lml, ERR_FATAL, 1999 MSG_INTL(MSG_MAP_SYMDEF1), mapfile, 2000 EC_XWORD(Line_num), demangle(_name), 2001 sdp->sd_file->ifl_name, conflict); 2002 } 2003 errcnt++; 2004 continue; 2005 } 2006 2007 /* 2008 * Indicate that this symbol has been explicitly 2009 * contributed from a mapfile. 2010 */ 2011 sdp->sd_flags1 |= (FLG_SY1_MAPFILE | FLG_SY1_EXPDEF); 2012 2013 /* 2014 * If we've encountered a symbol definition simulate 2015 * that an input file has been processed - this allows 2016 * things like filters to be created purely from a 2017 * mapfile. 2018 */ 2019 if (type != STT_NOTYPE) 2020 ofl->ofl_objscnt++; 2021 DBG_CALL(Dbg_map_symbol(ofl, sdp)); 2022 2023 /* 2024 * If this symbol has an associated filtee, record the 2025 * filtee string and associate the string index with the 2026 * symbol. This is used later to associate the syminfo 2027 * information with the necessary .dynamic entry. 2028 */ 2029 if (filter && (filtee == 0)) { 2030 eprintf(ofl->ofl_lml, ERR_FATAL, 2031 MSG_INTL(MSG_MAP_NOFILTER), mapfile, 2032 EC_XWORD(Line_num), _name); 2033 errcnt++; 2034 continue; 2035 } 2036 2037 if (filtee) { 2038 Dfltr_desc * dftp; 2039 Sfltr_desc sft; 2040 Aliste idx, _idx, nitems; 2041 2042 /* 2043 * Make sure we don't duplicate any filtee 2044 * strings, and create a new descriptor if 2045 * necessary. 2046 */ 2047 idx = nitems = alist_nitems(ofl->ofl_dtsfltrs); 2048 for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx, 2049 dftp)) { 2050 if ((dftflag != dftp->dft_flag) || 2051 (strcmp(dftp->dft_str, filtee))) 2052 continue; 2053 idx = _idx; 2054 break; 2055 } 2056 if (idx == nitems) { 2057 Dfltr_desc dft; 2058 2059 dft.dft_str = filtee; 2060 dft.dft_flag = dftflag; 2061 dft.dft_ndx = 0; 2062 2063 /* 2064 * The following append puts the new 2065 * item at the offset contained in 2066 * idx, because we know idx contains 2067 * the index of the next available slot. 2068 */ 2069 if (alist_append(&ofl->ofl_dtsfltrs, 2070 &dft, sizeof (Dfltr_desc), 2071 AL_CNT_OFL_DTSFLTRS) == NULL) 2072 return (S_ERROR); 2073 } 2074 2075 /* 2076 * Create a new filter descriptor for this 2077 * symbol. 2078 */ 2079 sft.sft_sdp = sdp; 2080 sft.sft_idx = idx; 2081 2082 if (alist_append(&ofl->ofl_symfltrs, 2083 &sft, sizeof (Sfltr_desc), 2084 AL_CNT_OFL_SYMFLTRS) == NULL) 2085 return (S_ERROR); 2086 } 2087 break; 2088 2089 default: 2090 eprintf(ofl->ofl_lml, ERR_FATAL, 2091 MSG_INTL(MSG_MAP_EXPSCOL), mapfile, 2092 EC_XWORD(Line_num)); 2093 errcnt++; 2094 continue; 2095 } 2096 } 2097 2098 if (errcnt) 2099 return (S_ERROR); 2100 2101 /* 2102 * Determine if any version references are provided after the close 2103 * bracket. 2104 */ 2105 while ((tok = gettoken(ofl, mapfile)) != TK_SEMICOLON) { 2106 Ver_desc *_vdp; 2107 char *_name; 2108 2109 if (tok != TK_STRING) { 2110 /* LINTED */ 2111 if (tok != (Token)S_ERROR) 2112 eprintf(ofl->ofl_lml, ERR_FATAL, 2113 MSG_INTL(MSG_MAP_EXPVERS), mapfile, 2114 EC_XWORD(Line_num)); 2115 return (S_ERROR); 2116 } 2117 2118 name = Start_tok; 2119 if (vdp->vd_ndx == VER_NDX_GLOBAL) { 2120 eprintf(ofl->ofl_lml, ERR_WARNING, 2121 MSG_INTL(MSG_MAP_UNEXDEP), mapfile, 2122 EC_XWORD(Line_num), name); 2123 continue; 2124 } 2125 2126 /* 2127 * Generate a new version descriptor if it doesn't already 2128 * exist. 2129 */ 2130 /* LINTED */ 2131 hash = (Word)elf_hash(name); 2132 if ((_vdp = ld_vers_find(name, hash, &ofl->ofl_verdesc)) == 0) { 2133 if ((_name = libld_malloc(strlen(name) + 1)) == 0) 2134 return (S_ERROR); 2135 (void) strcpy(_name, name); 2136 2137 if ((_vdp = ld_vers_desc(_name, hash, 2138 &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR) 2139 return (S_ERROR); 2140 } 2141 2142 /* 2143 * Add the new version descriptor to the parent version 2144 * descriptors reference list. Indicate the version descriptors 2145 * first reference (used for error disgnostics if undefined 2146 * version dependencies remain). 2147 */ 2148 if (ld_vers_find(name, hash, &vdp->vd_deps) == 0) 2149 if (list_appendc(&vdp->vd_deps, _vdp) == 0) 2150 return (S_ERROR); 2151 2152 if (_vdp->vd_ref == 0) 2153 _vdp->vd_ref = vdp; 2154 } 2155 return (1); 2156 } 2157 2158 /* 2159 * Sort the segment list by increasing virtual address. 2160 */ 2161 uintptr_t 2162 ld_sort_seg_list(Ofl_desc *ofl) 2163 { 2164 List seg1, seg2; 2165 Listnode *lnp1, *lnp2, *lnp3; 2166 Sg_desc *sgp1, *sgp2; 2167 2168 seg1.head = seg1.tail = seg2.head = seg2.tail = NULL; 2169 2170 /* 2171 * Add the .phdr and .interp segments to our list. These segments must 2172 * occur before any PT_LOAD segments (refer exec/elf/elf.c). Also add 2173 * the capabilities segment. This isn't essential, but the capabilities 2174 * section is one of the first in an object. 2175 */ 2176 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp1)) { 2177 Word type = sgp1->sg_phdr.p_type; 2178 2179 if ((type == PT_PHDR) || (type == PT_INTERP) || 2180 (type == PT_SUNWCAP)) { 2181 if (list_appendc(&seg1, sgp1) == 0) 2182 return (S_ERROR); 2183 } 2184 } 2185 2186 /* 2187 * Add the loadable segments to another list in sorted order. 2188 */ 2189 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp1)) { 2190 DBG_CALL(Dbg_map_sort_orig(ofl->ofl_lml, sgp1)); 2191 2192 if (sgp1->sg_phdr.p_type != PT_LOAD) 2193 continue; 2194 2195 if (!(sgp1->sg_flags & FLG_SG_VADDR) || 2196 (sgp1->sg_flags & FLG_SG_EMPTY)) { 2197 if (list_appendc(&seg2, sgp1) == 0) 2198 return (S_ERROR); 2199 } else { 2200 if (seg2.head == NULL) { 2201 if (list_appendc(&seg2, sgp1) == 0) 2202 return (S_ERROR); 2203 continue; 2204 } 2205 lnp3 = NULL; 2206 for (LIST_TRAVERSE(&seg2, lnp2, sgp2)) { 2207 if (!(sgp2->sg_flags & FLG_SG_VADDR) || 2208 (sgp2->sg_flags & FLG_SG_EMPTY)) { 2209 if (lnp3 == NULL) { 2210 if (list_prependc(&seg2, 2211 sgp1) == 0) 2212 return (S_ERROR); 2213 } else { 2214 if (list_insertc(&seg2, 2215 sgp1, lnp3) == 0) 2216 return (S_ERROR); 2217 } 2218 lnp3 = NULL; 2219 break; 2220 } 2221 if (sgp1->sg_phdr.p_vaddr < 2222 sgp2->sg_phdr.p_vaddr) { 2223 if (lnp3 == NULL) { 2224 if (list_prependc(&seg2, 2225 sgp1) == 0) 2226 return (S_ERROR); 2227 } else { 2228 if (list_insertc(&seg2, 2229 sgp1, lnp3) == 0) 2230 return (S_ERROR); 2231 } 2232 lnp3 = NULL; 2233 break; 2234 } else if (sgp1->sg_phdr.p_vaddr > 2235 sgp2->sg_phdr.p_vaddr) { 2236 lnp3 = lnp2; 2237 } else { 2238 eprintf(ofl->ofl_lml, ERR_FATAL, 2239 MSG_INTL(MSG_MAP_SEGSAME), 2240 sgp1->sg_name, sgp2->sg_name); 2241 return (S_ERROR); 2242 } 2243 } 2244 if (lnp3 != NULL) 2245 if (list_appendc(&seg2, sgp1) == 0) 2246 return (S_ERROR); 2247 } 2248 } 2249 2250 /* 2251 * Add the sorted loadable segments to our list. 2252 */ 2253 for (LIST_TRAVERSE(&seg2, lnp1, sgp1)) { 2254 if (list_appendc(&seg1, sgp1) == 0) 2255 return (S_ERROR); 2256 } 2257 2258 /* 2259 * Add all other segments to our list. 2260 */ 2261 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp1)) { 2262 Word type = sgp1->sg_phdr.p_type; 2263 2264 if ((type != PT_PHDR) && (type != PT_INTERP) && 2265 (type != PT_SUNWCAP) && (type != PT_LOAD)) { 2266 if (list_appendc(&seg1, sgp1) == 0) 2267 return (S_ERROR); 2268 } 2269 } 2270 ofl->ofl_segs.head = ofl->ofl_segs.tail = NULL; 2271 2272 /* 2273 * Now rebuild the original list and process all of the 2274 * segment/section ordering information if present. 2275 */ 2276 for (LIST_TRAVERSE(&seg1, lnp1, sgp1)) { 2277 DBG_CALL(Dbg_map_sort_fini(ofl->ofl_lml, sgp1)); 2278 if (list_appendc(&ofl->ofl_segs, sgp1) == 0) 2279 return (S_ERROR); 2280 } 2281 return (1); 2282 } 2283 2284 /* 2285 * Parse the mapfile. 2286 */ 2287 uintptr_t 2288 ld_map_parse(const char *mapfile, Ofl_desc *ofl) 2289 { 2290 struct stat stat_buf; /* stat of mapfile */ 2291 int mapfile_fd; /* descriptor for mapfile */ 2292 Listnode *lnp1; /* node pointer */ 2293 Listnode *lnp2; /* node pointer */ 2294 Sg_desc *sgp1; /* seg descriptor being manipulated */ 2295 Sg_desc *sgp2; /* temp segment descriptor pointer */ 2296 Ent_desc *enp; /* Segment entrance criteria. */ 2297 Token tok; /* current token. */ 2298 Listnode *e_next = NULL; 2299 /* next place for entrance criterion */ 2300 Boolean new_segment; /* If true, defines new segment. */ 2301 char *name; 2302 static int num_stack = 0; /* number of stack segment */ 2303 int err; 2304 2305 DBG_CALL(Dbg_map_parse(ofl->ofl_lml, mapfile)); 2306 2307 /* 2308 * Determine if we're dealing with a file or a directory. 2309 */ 2310 if (stat(mapfile, &stat_buf) == -1) { 2311 err = errno; 2312 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_STAT), 2313 mapfile, strerror(err)); 2314 return (S_ERROR); 2315 } 2316 if (S_ISDIR(stat_buf.st_mode)) { 2317 DIR *dirp; 2318 struct dirent *denp; 2319 2320 /* 2321 * Open the directory and interpret each visible file as a 2322 * mapfile. 2323 */ 2324 if ((dirp = opendir(mapfile)) == 0) 2325 return (1); 2326 2327 while ((denp = readdir(dirp)) != NULL) { 2328 char path[PATH_MAX]; 2329 2330 /* 2331 * Ignore any hidden filenames. Construct the full 2332 * pathname to the new mapfile. 2333 */ 2334 if (*denp->d_name == '.') 2335 continue; 2336 (void) snprintf(path, PATH_MAX, MSG_ORIG(MSG_STR_PATH), 2337 mapfile, denp->d_name); 2338 if (ld_map_parse(path, ofl) == S_ERROR) 2339 return (S_ERROR); 2340 } 2341 (void) closedir(dirp); 2342 return (1); 2343 } else if (!S_ISREG(stat_buf.st_mode)) { 2344 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_NOTREG), 2345 mapfile); 2346 return (S_ERROR); 2347 } 2348 2349 /* 2350 * We read the entire mapfile into memory. 2351 */ 2352 if ((Mapspace = libld_malloc(stat_buf.st_size + 1)) == 0) 2353 return (S_ERROR); 2354 if ((mapfile_fd = open(mapfile, O_RDONLY)) == -1) { 2355 err = errno; 2356 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), 2357 mapfile, strerror(err)); 2358 return (S_ERROR); 2359 } 2360 2361 if (read(mapfile_fd, Mapspace, stat_buf.st_size) != stat_buf.st_size) { 2362 err = errno; 2363 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_READ), 2364 mapfile, strerror(err)); 2365 return (S_ERROR); 2366 } 2367 Mapspace[stat_buf.st_size] = '\0'; 2368 nextchr = Mapspace; 2369 2370 /* 2371 * Set up any global variables, the line number counter and file name. 2372 */ 2373 Line_num = 1; 2374 2375 /* 2376 * We now parse the mapfile until the gettoken routine returns EOF. 2377 */ 2378 while ((tok = gettoken(ofl, mapfile)) != TK_EOF) { 2379 int ndx = -1; 2380 2381 /* 2382 * Don't know which segment yet. 2383 */ 2384 sgp1 = NULL; 2385 2386 /* 2387 * At this point we are at the beginning of a line, and the 2388 * variable `Start_tok' points to the first string on the line. 2389 * All mapfile entries start with some string token except it 2390 * is possible for a scoping definition to start with `{'. 2391 */ 2392 if (tok == TK_LEFTBKT) { 2393 if (map_version(mapfile, (char *)0, ofl) == S_ERROR) 2394 return (S_ERROR); 2395 continue; 2396 } 2397 if (tok != TK_STRING) { 2398 /* LINTED */ 2399 if (tok != (Token)S_ERROR) 2400 eprintf(ofl->ofl_lml, ERR_FATAL, 2401 MSG_INTL(MSG_MAP_EXPSEGNAM), mapfile, 2402 EC_XWORD(Line_num)); 2403 return (S_ERROR); 2404 } 2405 2406 /* 2407 * Save the initial token. 2408 */ 2409 if ((name = libld_malloc(strlen(Start_tok) + 1)) == 0) 2410 return (S_ERROR); 2411 (void) strcpy(name, Start_tok); 2412 2413 /* 2414 * Now check the second character on the line. The special `-' 2415 * and `{' characters do not involve any segment manipulation so 2416 * we handle them first. 2417 */ 2418 if ((tok = gettoken(ofl, mapfile)) == TK_DASH) { 2419 if (map_dash(mapfile, name, ofl) == S_ERROR) 2420 return (S_ERROR); 2421 continue; 2422 } 2423 if (tok == TK_LEFTBKT) { 2424 if (map_version(mapfile, name, ofl) == S_ERROR) 2425 return (S_ERROR); 2426 continue; 2427 } 2428 2429 /* 2430 * If we're here we need to interpret the first string as a 2431 * segment name. Find the segment named in the token. 2432 */ 2433 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp2)) { 2434 ndx++; 2435 if (strcmp(sgp2->sg_name, name) == 0) { 2436 sgp1 = sgp2; 2437 sgp2->sg_flags &= ~FLG_SG_DISABLED; 2438 new_segment = FALSE; 2439 break; 2440 } 2441 } 2442 2443 /* 2444 * If the second token is a '|' then we had better 2445 * of found a segment. It is illegal to perform 2446 * section within segment ordering before the segment 2447 * has been declared. 2448 */ 2449 if (tok == TK_PIPE) { 2450 if (sgp1 == NULL) { 2451 eprintf(ofl->ofl_lml, ERR_FATAL, 2452 MSG_INTL(MSG_MAP_SECINSEG), mapfile, 2453 EC_XWORD(Line_num), name); 2454 return (S_ERROR); 2455 } else { 2456 if (map_pipe(ofl, mapfile, sgp1) == S_ERROR) 2457 return (S_ERROR); 2458 continue; 2459 } 2460 } 2461 2462 /* 2463 * If segment is still NULL then it does not exist. Create a 2464 * new segment, and leave its values as 0 so that map_equal() 2465 * can detect changing attributes. 2466 */ 2467 if (sgp1 == NULL) { 2468 if ((sgp1 = libld_calloc(sizeof (Sg_desc), 2469 1)) == 0) 2470 return (S_ERROR); 2471 sgp1->sg_phdr.p_type = PT_NULL; 2472 sgp1->sg_name = name; 2473 new_segment = TRUE; 2474 ndx = -1; 2475 } 2476 2477 if ((strcmp(sgp1->sg_name, MSG_ORIG(MSG_STR_INTERP)) == 0) || 2478 (strcmp(sgp1->sg_name, MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 2479 0)) { 2480 eprintf(ofl->ofl_lml, ERR_FATAL, 2481 MSG_INTL(MSG_MAP_SEGRESV), mapfile, 2482 EC_XWORD(Line_num)); 2483 return (S_ERROR); 2484 } 2485 2486 /* 2487 * Now check the second token from the input line. 2488 */ 2489 if (tok == TK_EQUAL) { 2490 if (strcmp(sgp1->sg_name, 2491 MSG_ORIG(MSG_STR_HWCAP_1)) == 0) { 2492 if (map_cap(mapfile, CA_SUNW_HW_1, 2493 ofl) == S_ERROR) 2494 return (S_ERROR); 2495 DBG_CALL(Dbg_cap_mapfile(ofl->ofl_lml, 2496 CA_SUNW_HW_1, ofl->ofl_hwcap_1, 2497 ld_targ.t_m.m_mach)); 2498 continue; 2499 2500 } else if (strcmp(sgp1->sg_name, 2501 MSG_ORIG(MSG_STR_SFCAP_1)) == 0) { 2502 if (map_cap(mapfile, CA_SUNW_SF_1, 2503 ofl) == S_ERROR) 2504 return (S_ERROR); 2505 DBG_CALL(Dbg_cap_mapfile(ofl->ofl_lml, 2506 CA_SUNW_SF_1, ofl->ofl_sfcap_1, 2507 ld_targ.t_m.m_mach)); 2508 continue; 2509 2510 } else { 2511 if (map_equal(mapfile, sgp1, ofl) == S_ERROR) 2512 return (S_ERROR); 2513 ofl->ofl_flags |= FLG_OF_SEGSORT; 2514 DBG_CALL(Dbg_map_set_equal(new_segment)); 2515 } 2516 } else if (tok == TK_COLON) { 2517 /* 2518 * If this is an existing segment reservation, sections 2519 * can't be assigned to it. 2520 */ 2521 if ((new_segment == FALSE) && 2522 (sgp1->sg_flags & FLG_SG_EMPTY)) { 2523 eprintf(ofl->ofl_lml, ERR_FATAL, 2524 MSG_INTL(MSG_MAP_SEGEMPSEC), mapfile, 2525 EC_XWORD(Line_num)); 2526 return (S_ERROR); 2527 } 2528 2529 /* 2530 * We are looking at a new entrance criteria line. 2531 * Note that entrance criteria are added in the order 2532 * they are found in the map file, but are placed 2533 * before any default criteria. 2534 */ 2535 if ((enp = libld_calloc(sizeof (Ent_desc), 1)) == 0) 2536 return (S_ERROR); 2537 enp->ec_segment = sgp1; 2538 if (e_next == NULL) { 2539 if ((e_next = list_prependc(&ofl->ofl_ents, 2540 enp)) == 0) 2541 return (S_ERROR); 2542 } else { 2543 if ((e_next = list_insertc(&ofl->ofl_ents, 2544 enp, e_next)) == 0) 2545 return (S_ERROR); 2546 } 2547 2548 if (map_colon(ofl, mapfile, enp) == S_ERROR) 2549 return (S_ERROR); 2550 ofl->ofl_flags |= FLG_OF_SEGSORT; 2551 DBG_CALL(Dbg_map_ent(ofl->ofl_lml, new_segment, 2552 enp, ofl)); 2553 } else if (tok == TK_ATSIGN) { 2554 if (map_atsign(mapfile, sgp1, ofl) == S_ERROR) 2555 return (S_ERROR); 2556 DBG_CALL(Dbg_map_set_atsign(new_segment)); 2557 } else { 2558 /* LINTED */ 2559 if (tok != (Token)S_ERROR) { 2560 eprintf(ofl->ofl_lml, ERR_FATAL, 2561 MSG_INTL(MSG_MAP_EXPEQU), mapfile, 2562 EC_XWORD(Line_num)); 2563 return (S_ERROR); 2564 } 2565 } 2566 2567 /* 2568 * Having completed parsing an entry in the map file determine 2569 * if the segment to which it applies is new. 2570 */ 2571 if (new_segment) { 2572 int src_type, dst_type; 2573 2574 /* 2575 * If specific fields have not been supplied via 2576 * map_equal(), make sure defaults are supplied. 2577 */ 2578 if (((sgp1->sg_flags & FLG_SG_TYPE) == 0) && 2579 (sgp1->sg_phdr.p_type == PT_NULL)) { 2580 /* 2581 * Default to a loadable segment. 2582 */ 2583 sgp1->sg_phdr.p_type = PT_LOAD; 2584 sgp1->sg_flags |= FLG_SG_TYPE; 2585 } 2586 if (sgp1->sg_phdr.p_type == PT_LOAD) { 2587 if ((sgp1->sg_flags & FLG_SG_FLAGS) == 0) { 2588 /* 2589 * Default to read/write and execute. 2590 */ 2591 sgp1->sg_phdr.p_flags = 2592 PF_R + PF_W + PF_X; 2593 sgp1->sg_flags |= FLG_SG_FLAGS; 2594 } 2595 if ((sgp1->sg_flags & FLG_SG_ALIGN) == 0) { 2596 /* 2597 * Default to segment alignment 2598 */ 2599 sgp1->sg_phdr.p_align = 2600 ld_targ.t_m.m_segm_align; 2601 sgp1->sg_flags |= FLG_SG_ALIGN; 2602 } 2603 } 2604 2605 /* 2606 * Determine where the new segment should be inserted 2607 * in the seg_desc[] list. Presently the user can 2608 * only add a LOAD or NOTE segment. Note that these 2609 * segments must be added after any PT_PHDR and 2610 * PT_INTERP (refer Generic ABI, Page 5-4). 2611 */ 2612 switch (sgp1->sg_phdr.p_type) { 2613 case PT_LOAD: 2614 case PT_NULL: 2615 if (sgp1->sg_flags & FLG_SG_EMPTY) 2616 src_type = 4; 2617 else 2618 src_type = 3; 2619 break; 2620 case PT_SUNWSTACK: 2621 src_type = 8; 2622 if (++num_stack >= 2) { 2623 /* 2624 * Currently the number of sunw_stack 2625 * segment is limited to 1. 2626 */ 2627 eprintf(ofl->ofl_lml, ERR_WARNING, 2628 MSG_INTL(MSG_MAP_NOSTACK2), 2629 mapfile, EC_XWORD(Line_num)); 2630 continue; 2631 } 2632 break; 2633 case PT_NOTE: 2634 src_type = 9; 2635 break; 2636 default: 2637 eprintf(ofl->ofl_lml, ERR_FATAL, 2638 MSG_INTL(MSG_MAP_UNKSEGTYP), mapfile, 2639 EC_XWORD(Line_num), 2640 EC_WORD(sgp1->sg_phdr.p_type)); 2641 return (S_ERROR); 2642 } 2643 lnp2 = NULL; 2644 for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp2)) { 2645 ndx++; 2646 switch (sgp2->sg_phdr.p_type) { 2647 case PT_PHDR: 2648 dst_type = 0; 2649 break; 2650 case PT_INTERP: 2651 dst_type = 1; 2652 break; 2653 case PT_SUNWCAP: 2654 dst_type = 2; 2655 break; 2656 case PT_LOAD: 2657 dst_type = 3; 2658 break; 2659 case PT_DYNAMIC: 2660 dst_type = 5; 2661 break; 2662 case PT_SUNWDTRACE: 2663 dst_type = 6; 2664 break; 2665 case PT_SHLIB: 2666 dst_type = 7; 2667 break; 2668 case PT_SUNWSTACK: 2669 dst_type = 8; 2670 break; 2671 case PT_NOTE: 2672 dst_type = 9; 2673 break; 2674 case PT_SUNWBSS: 2675 dst_type = 10; 2676 break; 2677 case PT_TLS: 2678 dst_type = 11; 2679 break; 2680 case PT_NULL: 2681 dst_type = 12; 2682 break; 2683 default: 2684 eprintf(ofl->ofl_lml, ERR_FATAL, 2685 MSG_INTL(MSG_MAP_UNKSEGTYP), 2686 mapfile, EC_XWORD(Line_num), 2687 EC_WORD(sgp2->sg_phdr.p_type)); 2688 return (S_ERROR); 2689 } 2690 if (src_type <= dst_type) { 2691 if (lnp2 == NULL) { 2692 if (list_prependc( 2693 &ofl->ofl_segs, sgp1) == 0) 2694 return (S_ERROR); 2695 } else { 2696 if (list_insertc(&ofl->ofl_segs, 2697 sgp1, lnp2) == 0) 2698 return (S_ERROR); 2699 } 2700 break; 2701 } 2702 lnp2 = lnp1; 2703 } 2704 } 2705 DBG_CALL(Dbg_map_seg(ofl, ndx, sgp1)); 2706 } 2707 2708 /* 2709 * If the output file is a static file without an interpreter, and 2710 * if any virtual address is specified, then set the ?N flag for 2711 * backward compatibility. 2712 */ 2713 if (!(ofl->ofl_flags & FLG_OF_DYNAMIC) && 2714 !(ofl->ofl_flags & FLG_OF_RELOBJ) && 2715 !(ofl->ofl_osinterp) && 2716 (ofl->ofl_flags1 & FLG_OF1_VADDR)) 2717 ofl->ofl_dtflags_1 |= DF_1_NOHDR; 2718 2719 /* 2720 * If the output file is a relocatable file, then ?N has no effect. 2721 * Make sure this flag isn't set. 2722 */ 2723 if (ofl->ofl_flags & FLG_OF_RELOBJ) 2724 ofl->ofl_dtflags_1 &= ~DF_1_NOHDR; 2725 2726 return (1); 2727 } 2728