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 (c) 2010, Oracle and/or its affiliates. All rights reserved. 27 */ 28 29 /* 30 * Map file parsing (Shared Core Code). 31 */ 32 #include <fcntl.h> 33 #include <stdio.h> 34 #include <unistd.h> 35 #include <sys/stat.h> 36 #include <errno.h> 37 #include <limits.h> 38 #include <dirent.h> 39 #include <ctype.h> 40 #include <debug.h> 41 #include "msg.h" 42 #include "_libld.h" 43 #include "_map.h" 44 45 /* 46 * There are two styles of mapfile supported by the link-editor: 47 * 48 * 1) The original System V defined syntax, as augmented at Sun 49 * from Solaris 2.0 through Solaris 10. This style is also known 50 * as version 1. 51 * 52 * 2) A newer syntax, currently at version 2. 53 * 54 * The original syntax uses special characters (=, :, -, |, etc) as 55 * operators to indicate the operation being specified. Over the years, 56 * this syntax has been problematic: 57 * 58 * 1) Too cryptic: It's hard for people to remember which character 59 * means what. 60 * 61 * 2) Limited expansion potential: There only a few special characters 62 * available on the keyboard for new features, and it is difficult to 63 * add options to existing ones. 64 * 65 * Adding new features into this framework (2) have the effect of 66 * making the syntax even more cryptic (1). The newer syntax addresses 67 * these issues by moving to an extendible identifier based syntax that 68 * allows new features to be added without complicating old ones. 69 * 70 * The new syntax uses the following terminology: 71 * 72 * - Control directives are the directives that start with a '$'. 73 * They control how the mapfile is interpreted. We use the 'cdir_' 74 * prefix on functions and variables related to these directives. 75 * 76 * - Conditional Expressions are the expressions found in $if and $elif 77 * control directives. They evaluate to boolean true/false values. 78 * We use the 'cexp_' prefix for functions and variables related to 79 * these expressions. 80 * 81 * - Regular Directives are names (SYMBOL, VERSION, etc) that convey 82 * directions to the link-editor for building the output object. 83 * 84 * This file contains core code used by both mapfile styles: File management, 85 * lexical analysis, and other shared core functionality. It also contains 86 * the code for control directives, as they are intrinsically part of 87 * lexical analysis --- this is disabled when processing Sysv mapfiles. 88 */ 89 90 /* 91 * We use a stack of cdir_level_t structs to manage $if/$elif/$else/$endif 92 * processing. At each level, we keep track of the information needed to 93 * determine whether or not to process nested input lines or skip them, 94 * along with information needed to report errors. 95 */ 96 typedef struct { 97 Lineno cdl_if_lineno; /* Line number of opening $if */ 98 Lineno cdl_else_lineno; /* 0, or line on which $else seen */ 99 int cdl_done; /* True if no longer accepts input */ 100 int cdl_pass; /* True if currently accepting input */ 101 } cdir_level_t; 102 103 /* Operators in the expressions accepted by $if/$elif */ 104 typedef enum { 105 CEXP_OP_NONE, /* Not an operator */ 106 CEXP_OP_AND, /* && */ 107 CEXP_OP_OR, /* || */ 108 CEXP_OP_NEG, /* ! */ 109 CEXP_OP_OPAR, /* ( */ 110 CEXP_OP_CPAR /* ) */ 111 } cexp_op_t; 112 113 /* 114 * Type of conditional expression identifier AVL tree nodes 115 */ 116 typedef struct cexp_name_node { 117 avl_node_t ceid_avlnode; /* AVL book-keeping */ 118 const char *ceid_name; /* boolean identifier name */ 119 } cexp_id_node_t; 120 121 122 /* 123 * Declare a "stack" type, containing a pointer to data, a count of 124 * allocated, and currently used items in the stack. The data type 125 * is specified as the _type argument. 126 */ 127 #define STACK(_type) \ 128 struct { \ 129 _type *stk_s; /* Stack array */ \ 130 size_t stk_n; /* Current stack depth */ \ 131 size_t stk_n_alloc; /* # of elements pointed at by s */ \ 132 } 133 134 /* 135 * The following type represents a "generic" stack, where the data 136 * type is (void). This type is never instantiated. However, it has 137 * the same struct layout as any other STACK(), and is therefore a good 138 * generic type that can be used for stack_resize(). 139 */ 140 typedef STACK(void) generic_stack_t; 141 142 /* 143 * Ensure that the stack has enough room to push one more item 144 */ 145 #define STACK_RESERVE(_stack, _n_default) \ 146 (((_stack).stk_n < (_stack).stk_n_alloc) || \ 147 stack_resize((generic_stack_t *)&(_stack).stk_s, _n_default, \ 148 sizeof (*(_stack).stk_s))) 149 150 /* 151 * Reset a stack to empty. 152 */ 153 #define STACK_RESET(_stack) (_stack).stk_n = 0; 154 155 /* 156 * True if stack is empty, False otherwise. 157 */ 158 #define STACK_IS_EMPTY(_stack) ((_stack).stk_n == 0) 159 160 /* 161 * Push a value onto a stack. Caller must ensure that stack has room. 162 * This macro is intended to be used as the LHS of an assignment, the 163 * RHS of which is the value: 164 * 165 * STACK_PUSH(stack) = value; 166 */ 167 #define STACK_PUSH(_stack) (_stack).stk_s[(_stack).stk_n++] 168 169 /* 170 * Pop a value off a stack. Caller must ensure 171 * that stack is not empty. 172 */ 173 #define STACK_POP(_stack) ((_stack).stk_s[--(_stack).stk_n]) 174 175 /* 176 * Access top element on stack without popping. Caller must ensure 177 * that stack is not empty. 178 */ 179 #define STACK_TOP(_stack) (((_stack).stk_s)[(_stack).stk_n - 1]) 180 181 /* 182 * Initial sizes used for the stacks: The stacks are allocated on demand 183 * to these sizes, and then doubled as necessary until they are large enough. 184 * 185 * The ideal size would be large enough that only a single allocation 186 * occurs, and our defaults should generally have that effect. However, 187 * in doing so, we run the risk of a latent error in the resize code going 188 * undetected until triggered by a large task in the field. For this reason, 189 * we set the sizes to the smallest size possible when compiled for debug. 190 */ 191 #ifdef DEBUG 192 #define CDIR_STACK_INIT 1 193 #define CEXP_OP_STACK_INIT 1 194 #define CEXP_VAL_STACK_INIT 1 195 #else 196 #define CDIR_STACK_INIT 16 197 #define CEXP_OP_STACK_INIT 8 198 #define CEXP_VAL_STACK_INIT (CEXP_OP_STACK_INIT * 2) /* 2 vals per binop */ 199 #endif 200 201 202 /* 203 * Persistent state maintained by map module in between calls. 204 * 205 * This is kept as static file scope data, because it is only used 206 * when libld is called by ld, and not by rtld. If that should change, 207 * the code is designed so that it can become reentrant easily: 208 * 209 * - Add a pointer to the output descriptor to a structure of this type, 210 * allocated dynamically on the first call to ld_map_parse(). 211 * - Change all references to lms to instead reference the pointer in 212 * the output descriptor. 213 * 214 * Until then, it is simpler not to expose these details. 215 */ 216 typedef struct { 217 int lms_cdir_valid; /* Allow control dir. on entry to gettoken() */ 218 STACK(cdir_level_t) lms_cdir_stack; /* Conditional input level */ 219 STACK(cexp_op_t) lms_cexp_op_stack; /* Cond. expr operators */ 220 STACK(uchar_t) lms_cexp_val_stack; /* Cond. expr values */ 221 avl_tree_t *lms_cexp_id; 222 } ld_map_state_t; 223 static ld_map_state_t lms; 224 225 226 /* 227 * Version 1 (SysV) syntax dispatch table for ld_map_gettoken(). For each 228 * of the 7-bit ASCII characters, determine how the lexical analyzer 229 * should behave. 230 * 231 * This table must be kept in sync with tkid_attr[] below. 232 * 233 * Identifier Note: 234 * The Linker and Libraries Guide states that the original syntax uses 235 * C identifier rules, allowing '.' to be treated as a letter. However, 236 * the implementation is considerably looser than that: Any character 237 * with an ASCII code (0-127) which is printable and not used to start 238 * another token is allowed to start an identifier, and they are terminated 239 * by any of: space, double quote, tab, newline, ':', ';', '=', or '#'. 240 * The original code has been replaced, but this table encodes the same 241 * rules, to ensure backward compatibility. 242 */ 243 static const mf_tokdisp_t gettok_dispatch_v1 = { 244 TK_OP_EOF, /* 0 - NUL */ 245 TK_OP_ILLCHR, /* 1 - SOH */ 246 TK_OP_ILLCHR, /* 2 - STX */ 247 TK_OP_ILLCHR, /* 3 - ETX */ 248 TK_OP_ILLCHR, /* 4 - EOT */ 249 TK_OP_ILLCHR, /* 5 - ENQ */ 250 TK_OP_ILLCHR, /* 6 - ACK */ 251 TK_OP_ILLCHR, /* 7 - BEL */ 252 TK_OP_ILLCHR, /* 8 - BS */ 253 TK_OP_WS, /* 9 - HT */ 254 TK_OP_NL, /* 10 - NL */ 255 TK_OP_WS, /* 11 - VT */ 256 TK_OP_WS, /* 12 - FF */ 257 TK_OP_WS, /* 13 - CR */ 258 TK_OP_ILLCHR, /* 14 - SO */ 259 TK_OP_ILLCHR, /* 15 - SI */ 260 TK_OP_ILLCHR, /* 16 - DLE */ 261 TK_OP_ILLCHR, /* 17 - DC1 */ 262 TK_OP_ILLCHR, /* 18 - DC2 */ 263 TK_OP_ILLCHR, /* 19 - DC3 */ 264 TK_OP_ILLCHR, /* 20 - DC4 */ 265 TK_OP_ILLCHR, /* 21 - NAK */ 266 TK_OP_ILLCHR, /* 22 - SYN */ 267 TK_OP_ILLCHR, /* 23 - ETB */ 268 TK_OP_ILLCHR, /* 24 - CAN */ 269 TK_OP_ILLCHR, /* 25 - EM */ 270 TK_OP_ILLCHR, /* 26 - SUB */ 271 TK_OP_ILLCHR, /* 27 - ESC */ 272 TK_OP_ILLCHR, /* 28 - FS */ 273 TK_OP_ILLCHR, /* 29 - GS */ 274 TK_OP_ILLCHR, /* 30 - RS */ 275 TK_OP_ILLCHR, /* 31 - US */ 276 TK_OP_WS, /* 32 - SP */ 277 TK_OP_ID, /* 33 - ! */ 278 TK_OP_SIMQUOTE, /* 34 - " */ 279 TK_OP_CMT, /* 35 - # */ 280 TK_OP_ID, /* 36 - $ */ 281 TK_OP_ID, /* 37 - % */ 282 TK_OP_ID, /* 38 - & */ 283 TK_OP_ID, /* 39 - ' */ 284 TK_OP_ID, /* 40 - ( */ 285 TK_OP_ID, /* 41 - ) */ 286 TK_OP_ID, /* 42 - * */ 287 TK_OP_ID, /* 43 - + */ 288 TK_OP_ID, /* 44 - , */ 289 TK_DASH, /* 45 - - */ 290 TK_OP_ID, /* 46 - . */ 291 TK_OP_ID, /* 47 - / */ 292 TK_OP_ID, /* 48 - 0 */ 293 TK_OP_ID, /* 49 - 1 */ 294 TK_OP_ID, /* 50 - 2 */ 295 TK_OP_ID, /* 51 - 3 */ 296 TK_OP_ID, /* 52 - 4 */ 297 TK_OP_ID, /* 53 - 5 */ 298 TK_OP_ID, /* 54 - 6 */ 299 TK_OP_ID, /* 55 - 7 */ 300 TK_OP_ID, /* 56 - 8 */ 301 TK_OP_ID, /* 57 - 9 */ 302 TK_COLON, /* 58 - : */ 303 TK_SEMICOLON, /* 59 - ; */ 304 TK_OP_ID, /* 60 - < */ 305 TK_EQUAL, /* 61 - = */ 306 TK_OP_ID, /* 62 - > */ 307 TK_OP_ID, /* 63 - ? */ 308 TK_ATSIGN, /* 64 - @ */ 309 TK_OP_ID, /* 65 - A */ 310 TK_OP_ID, /* 66 - B */ 311 TK_OP_ID, /* 67 - C */ 312 TK_OP_ID, /* 68 - D */ 313 TK_OP_ID, /* 69 - E */ 314 TK_OP_ID, /* 70 - F */ 315 TK_OP_ID, /* 71 - G */ 316 TK_OP_ID, /* 72 - H */ 317 TK_OP_ID, /* 73 - I */ 318 TK_OP_ID, /* 74 - J */ 319 TK_OP_ID, /* 75 - K */ 320 TK_OP_ID, /* 76 - L */ 321 TK_OP_ID, /* 77 - M */ 322 TK_OP_ID, /* 78 - N */ 323 TK_OP_ID, /* 79 - O */ 324 TK_OP_ID, /* 80 - P */ 325 TK_OP_ID, /* 81 - Q */ 326 TK_OP_ID, /* 82 - R */ 327 TK_OP_ID, /* 83 - S */ 328 TK_OP_ID, /* 84 - T */ 329 TK_OP_ID, /* 85 - U */ 330 TK_OP_ID, /* 86 - V */ 331 TK_OP_ID, /* 87 - W */ 332 TK_OP_ID, /* 88 - X */ 333 TK_OP_ID, /* 89 - Y */ 334 TK_OP_ID, /* 90 - Z */ 335 TK_OP_ID, /* 91 - [ */ 336 TK_OP_ID, /* 92 - \ */ 337 TK_OP_ID, /* 93 - ] */ 338 TK_OP_ID, /* 94 - ^ */ 339 TK_OP_ID, /* 95 - _ */ 340 TK_OP_ID, /* 96 - ` */ 341 TK_OP_ID, /* 97 - a */ 342 TK_OP_ID, /* 98 - b */ 343 TK_OP_ID, /* 99 - c */ 344 TK_OP_ID, /* 100 - d */ 345 TK_OP_ID, /* 101 - e */ 346 TK_OP_ID, /* 102 - f */ 347 TK_OP_ID, /* 103 - g */ 348 TK_OP_ID, /* 104 - h */ 349 TK_OP_ID, /* 105 - i */ 350 TK_OP_ID, /* 106 - j */ 351 TK_OP_ID, /* 107 - k */ 352 TK_OP_ID, /* 108 - l */ 353 TK_OP_ID, /* 109 - m */ 354 TK_OP_ID, /* 110 - n */ 355 TK_OP_ID, /* 111 - o */ 356 TK_OP_ID, /* 112 - p */ 357 TK_OP_ID, /* 113 - q */ 358 TK_OP_ID, /* 114 - r */ 359 TK_OP_ID, /* 115 - s */ 360 TK_OP_ID, /* 116 - t */ 361 TK_OP_ID, /* 117 - u */ 362 TK_OP_ID, /* 118 - v */ 363 TK_OP_ID, /* 119 - w */ 364 TK_OP_ID, /* 120 - x */ 365 TK_OP_ID, /* 121 - y */ 366 TK_OP_ID, /* 122 - z */ 367 TK_LEFTBKT, /* 123 - { */ 368 TK_PIPE, /* 124 - | */ 369 TK_RIGHTBKT, /* 125 - } */ 370 TK_OP_ID, /* 126 - ~ */ 371 TK_OP_ILLCHR, /* 127 - DEL */ 372 }; 373 374 /* 375 * Version 2 syntax dispatch table for ld_map_gettoken(). For each of the 376 * 7-bit ASCII characters, determine how the lexical analyzer should behave. 377 * 378 * This table must be kept in sync with tkid_attr[] below. 379 * 380 * Identifier Note: 381 * We define a letter as being one of the character [A-Z], [a-z], or [_%/.] 382 * A digit is the numbers [0-9], or [$-]. An unquoted identifier is defined 383 * as a letter, followed by any number of letters or digits. This is a loosened 384 * version of the C definition of an identifier. The extra characters not 385 * allowed by C are common in section names and/or file paths. 386 */ 387 static const mf_tokdisp_t gettok_dispatch_v2 = { 388 TK_OP_EOF, /* 0 - NUL */ 389 TK_OP_ILLCHR, /* 1 - SOH */ 390 TK_OP_ILLCHR, /* 2 - STX */ 391 TK_OP_ILLCHR, /* 3 - ETX */ 392 TK_OP_ILLCHR, /* 4 - EOT */ 393 TK_OP_ILLCHR, /* 5 - ENQ */ 394 TK_OP_ILLCHR, /* 6 - ACK */ 395 TK_OP_ILLCHR, /* 7 - BEL */ 396 TK_OP_ILLCHR, /* 8 - BS */ 397 TK_OP_WS, /* 9 - HT */ 398 TK_OP_NL, /* 10 - NL */ 399 TK_OP_WS, /* 11 - VT */ 400 TK_OP_WS, /* 12 - FF */ 401 TK_OP_WS, /* 13 - CR */ 402 TK_OP_ILLCHR, /* 14 - SO */ 403 TK_OP_ILLCHR, /* 15 - SI */ 404 TK_OP_ILLCHR, /* 16 - DLE */ 405 TK_OP_ILLCHR, /* 17 - DC1 */ 406 TK_OP_ILLCHR, /* 18 - DC2 */ 407 TK_OP_ILLCHR, /* 19 - DC3 */ 408 TK_OP_ILLCHR, /* 20 - DC4 */ 409 TK_OP_ILLCHR, /* 21 - NAK */ 410 TK_OP_ILLCHR, /* 22 - SYN */ 411 TK_OP_ILLCHR, /* 23 - ETB */ 412 TK_OP_ILLCHR, /* 24 - CAN */ 413 TK_OP_ILLCHR, /* 25 - EM */ 414 TK_OP_ILLCHR, /* 26 - SUB */ 415 TK_OP_ILLCHR, /* 27 - ESC */ 416 TK_OP_ILLCHR, /* 28 - FS */ 417 TK_OP_ILLCHR, /* 29 - GS */ 418 TK_OP_ILLCHR, /* 30 - RS */ 419 TK_OP_ILLCHR, /* 31 - US */ 420 TK_OP_WS, /* 32 - SP */ 421 TK_BANG, /* 33 - ! */ 422 TK_OP_CQUOTE, /* 34 - " */ 423 TK_OP_CMT, /* 35 - # */ 424 TK_OP_CDIR, /* 36 - $ */ 425 TK_OP_ID, /* 37 - % */ 426 TK_OP_BADCHR, /* 38 - & */ 427 TK_OP_SIMQUOTE, /* 39 - ' */ 428 TK_OP_BADCHR, /* 40 - ( */ 429 TK_OP_BADCHR, /* 41 - ) */ 430 TK_STAR, /* 42 - * */ 431 TK_OP_CEQUAL, /* 43 - + */ 432 TK_OP_BADCHR, /* 44 - , */ 433 TK_OP_CEQUAL, /* 45 - - */ 434 TK_OP_ID, /* 46 - . */ 435 TK_OP_ID, /* 47 - / */ 436 TK_OP_NUM, /* 48 - 0 */ 437 TK_OP_NUM, /* 49 - 1 */ 438 TK_OP_NUM, /* 50 - 2 */ 439 TK_OP_NUM, /* 51 - 3 */ 440 TK_OP_NUM, /* 52 - 4 */ 441 TK_OP_NUM, /* 53 - 5 */ 442 TK_OP_NUM, /* 54 - 6 */ 443 TK_OP_NUM, /* 55 - 7 */ 444 TK_OP_NUM, /* 56 - 8 */ 445 TK_OP_NUM, /* 57 - 9 */ 446 TK_COLON, /* 58 - : */ 447 TK_SEMICOLON, /* 59 - ; */ 448 TK_OP_BADCHR, /* 60 - < */ 449 TK_EQUAL, /* 61 - = */ 450 TK_OP_BADCHR, /* 62 - > */ 451 TK_OP_BADCHR, /* 63 - ? */ 452 TK_OP_BADCHR, /* 64 - @ */ 453 TK_OP_ID, /* 65 - A */ 454 TK_OP_ID, /* 66 - B */ 455 TK_OP_ID, /* 67 - C */ 456 TK_OP_ID, /* 68 - D */ 457 TK_OP_ID, /* 69 - E */ 458 TK_OP_ID, /* 70 - F */ 459 TK_OP_ID, /* 71 - G */ 460 TK_OP_ID, /* 72 - H */ 461 TK_OP_ID, /* 73 - I */ 462 TK_OP_ID, /* 74 - J */ 463 TK_OP_ID, /* 75 - K */ 464 TK_OP_ID, /* 76 - L */ 465 TK_OP_ID, /* 77 - M */ 466 TK_OP_ID, /* 78 - N */ 467 TK_OP_ID, /* 79 - O */ 468 TK_OP_ID, /* 80 - P */ 469 TK_OP_ID, /* 81 - Q */ 470 TK_OP_ID, /* 82 - R */ 471 TK_OP_ID, /* 83 - S */ 472 TK_OP_ID, /* 84 - T */ 473 TK_OP_ID, /* 85 - U */ 474 TK_OP_ID, /* 86 - V */ 475 TK_OP_ID, /* 87 - W */ 476 TK_OP_ID, /* 88 - X */ 477 TK_OP_ID, /* 89 - Y */ 478 TK_OP_ID, /* 90 - Z */ 479 TK_OP_BADCHR, /* 91 - [ */ 480 TK_OP_BADCHR, /* 92 - \ */ 481 TK_OP_BADCHR, /* 93 - ] */ 482 TK_OP_BADCHR, /* 94 - ^ */ 483 TK_OP_ID, /* 95 - _ */ 484 TK_OP_BADCHR, /* 96 - ` */ 485 TK_OP_ID, /* 97 - a */ 486 TK_OP_ID, /* 98 - b */ 487 TK_OP_ID, /* 99 - c */ 488 TK_OP_ID, /* 100 - d */ 489 TK_OP_ID, /* 101 - e */ 490 TK_OP_ID, /* 102 - f */ 491 TK_OP_ID, /* 103 - g */ 492 TK_OP_ID, /* 104 - h */ 493 TK_OP_ID, /* 105 - i */ 494 TK_OP_ID, /* 106 - j */ 495 TK_OP_ID, /* 107 - k */ 496 TK_OP_ID, /* 108 - l */ 497 TK_OP_ID, /* 109 - m */ 498 TK_OP_ID, /* 110 - n */ 499 TK_OP_ID, /* 111 - o */ 500 TK_OP_ID, /* 112 - p */ 501 TK_OP_ID, /* 113 - q */ 502 TK_OP_ID, /* 114 - r */ 503 TK_OP_ID, /* 115 - s */ 504 TK_OP_ID, /* 116 - t */ 505 TK_OP_ID, /* 117 - u */ 506 TK_OP_ID, /* 118 - v */ 507 TK_OP_ID, /* 119 - w */ 508 TK_OP_ID, /* 120 - x */ 509 TK_OP_ID, /* 121 - y */ 510 TK_OP_ID, /* 122 - z */ 511 TK_LEFTBKT, /* 123 - { */ 512 TK_OP_BADCHR, /* 124 - | */ 513 TK_RIGHTBKT, /* 125 - } */ 514 TK_OP_BADCHR, /* 126 - ~ */ 515 TK_OP_ILLCHR, /* 127 - DEL */ 516 }; 517 518 519 /* 520 * Table used to identify unquoted identifiers. Each element of this array 521 * contains a bitmask indicating whether the character it represents starts, 522 * or continues an identifier, for each supported mapfile syntax version. 523 */ 524 static const char tkid_attr[128] = { 525 0, /* 0 - NUL */ 526 TKID_ATTR_CONT(1), /* 1 - SOH */ 527 TKID_ATTR_CONT(1), /* 2 - STX */ 528 TKID_ATTR_CONT(1), /* 3 - ETX */ 529 TKID_ATTR_CONT(1), /* 4 - EOT */ 530 TKID_ATTR_CONT(1), /* 5 - ENQ */ 531 TKID_ATTR_CONT(1), /* 6 - ACK */ 532 TKID_ATTR_CONT(1), /* 7 - BEL */ 533 TKID_ATTR_CONT(1), /* 8 - BS */ 534 0, /* 9 - HT */ 535 0, /* 10 - NL */ 536 TKID_ATTR_CONT(1), /* 11 - VT */ 537 TKID_ATTR_CONT(1), /* 12 - FF */ 538 TKID_ATTR_CONT(1), /* 13 - CR */ 539 TKID_ATTR_CONT(1), /* 14 - SO */ 540 TKID_ATTR_CONT(1), /* 15 - SI */ 541 TKID_ATTR_CONT(1), /* 16 - DLE */ 542 TKID_ATTR_CONT(1), /* 17 - DC1 */ 543 TKID_ATTR_CONT(1), /* 18 - DC2 */ 544 TKID_ATTR_CONT(1), /* 19 - DC3 */ 545 TKID_ATTR_CONT(1), /* 20 - DC4 */ 546 TKID_ATTR_CONT(1), /* 21 - NAK */ 547 TKID_ATTR_CONT(1), /* 22 - SYN */ 548 TKID_ATTR_CONT(1), /* 23 - ETB */ 549 TKID_ATTR_CONT(1), /* 24 - CAN */ 550 TKID_ATTR_CONT(1), /* 25 - EM */ 551 TKID_ATTR_CONT(1), /* 26 - SUB */ 552 TKID_ATTR_CONT(1), /* 27 - ESC */ 553 TKID_ATTR_CONT(1), /* 28 - FS */ 554 TKID_ATTR_CONT(1), /* 29 - GS */ 555 TKID_ATTR_CONT(1), /* 30 - RS */ 556 TKID_ATTR_CONT(1), /* 31 - US */ 557 0, /* 32 - SP */ 558 TKID_ATTR(1), /* 33 - ! */ 559 0, /* 34 - " */ 560 0, /* 35 - # */ 561 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 36 - $ */ 562 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 37 - % */ 563 TKID_ATTR(1), /* 38 - & */ 564 TKID_ATTR(1), /* 39 - ' */ 565 TKID_ATTR(1), /* 40 - ( */ 566 TKID_ATTR(1), /* 41 - ) */ 567 TKID_ATTR(1), /* 42 - * */ 568 TKID_ATTR(1), /* 43 - + */ 569 TKID_ATTR(1), /* 44 - , */ 570 TKID_ATTR_CONT(1) | TKID_ATTR_CONT(2), /* 45 - - */ 571 TKID_ATTR(1) | TKID_ATTR(2), /* 46 - . */ 572 TKID_ATTR(1) | TKID_ATTR(2), /* 47 - / */ 573 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 48 - 0 */ 574 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 49 - 1 */ 575 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 50 - 2 */ 576 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 51 - 3 */ 577 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 52 - 4 */ 578 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 53 - 5 */ 579 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 54 - 6 */ 580 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 55 - 7 */ 581 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 56 - 8 */ 582 TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 57 - 9 */ 583 0, /* 58 - : */ 584 0, /* 59 - ; */ 585 TKID_ATTR(1), /* 60 - < */ 586 0, /* 61 - = */ 587 TKID_ATTR(1), /* 62 - > */ 588 TKID_ATTR(1), /* 63 - ? */ 589 TKID_ATTR_CONT(1), /* 64 - @ */ 590 TKID_ATTR(1) | TKID_ATTR(2), /* 65 - A */ 591 TKID_ATTR(1) | TKID_ATTR(2), /* 66 - B */ 592 TKID_ATTR(1) | TKID_ATTR(2), /* 67 - C */ 593 TKID_ATTR(1) | TKID_ATTR(2), /* 68 - D */ 594 TKID_ATTR(1) | TKID_ATTR(2), /* 69 - E */ 595 TKID_ATTR(1) | TKID_ATTR(2), /* 70 - F */ 596 TKID_ATTR(1) | TKID_ATTR(2), /* 71 - G */ 597 TKID_ATTR(1) | TKID_ATTR(2), /* 72 - H */ 598 TKID_ATTR(1) | TKID_ATTR(2), /* 73 - I */ 599 TKID_ATTR(1) | TKID_ATTR(2), /* 74 - J */ 600 TKID_ATTR(1) | TKID_ATTR(2), /* 75 - K */ 601 TKID_ATTR(1) | TKID_ATTR(2), /* 76 - L */ 602 TKID_ATTR(1) | TKID_ATTR(2), /* 77 - M */ 603 TKID_ATTR(1) | TKID_ATTR(2), /* 78 - N */ 604 TKID_ATTR(1) | TKID_ATTR(2), /* 79 - O */ 605 TKID_ATTR(1) | TKID_ATTR(2), /* 80 - P */ 606 TKID_ATTR(1) | TKID_ATTR(2), /* 81 - Q */ 607 TKID_ATTR(1) | TKID_ATTR(2), /* 82 - R */ 608 TKID_ATTR(1) | TKID_ATTR(2), /* 83 - S */ 609 TKID_ATTR(1) | TKID_ATTR(2), /* 84 - T */ 610 TKID_ATTR(1) | TKID_ATTR(2), /* 85 - U */ 611 TKID_ATTR(1) | TKID_ATTR(2), /* 86 - V */ 612 TKID_ATTR(1) | TKID_ATTR(2), /* 87 - W */ 613 TKID_ATTR(1) | TKID_ATTR(2), /* 88 - X */ 614 TKID_ATTR(1) | TKID_ATTR(2), /* 89 - Y */ 615 TKID_ATTR(1) | TKID_ATTR(2), /* 90 - Z */ 616 TKID_ATTR(1), /* 91 - [ */ 617 TKID_ATTR(1), /* 92 - \ */ 618 TKID_ATTR(1), /* 93 - ] */ 619 TKID_ATTR(1), /* 94 - ^ */ 620 TKID_ATTR(1) | TKID_ATTR(2), /* 95 - _ */ 621 TKID_ATTR(1), /* 96 - ` */ 622 TKID_ATTR(1) | TKID_ATTR(2), /* 97 - a */ 623 TKID_ATTR(1) | TKID_ATTR(2), /* 98 - b */ 624 TKID_ATTR(1) | TKID_ATTR(2), /* 99 - c */ 625 TKID_ATTR(1) | TKID_ATTR(2), /* 100 - d */ 626 TKID_ATTR(1) | TKID_ATTR(2), /* 101 - e */ 627 TKID_ATTR(1) | TKID_ATTR(2), /* 102 - f */ 628 TKID_ATTR(1) | TKID_ATTR(2), /* 103 - g */ 629 TKID_ATTR(1) | TKID_ATTR(2), /* 104 - h */ 630 TKID_ATTR(1) | TKID_ATTR(2), /* 105 - i */ 631 TKID_ATTR(1) | TKID_ATTR(2), /* 106 - j */ 632 TKID_ATTR(1) | TKID_ATTR(2), /* 107 - k */ 633 TKID_ATTR(1) | TKID_ATTR(2), /* 108 - l */ 634 TKID_ATTR(1) | TKID_ATTR(2), /* 109 - m */ 635 TKID_ATTR(1) | TKID_ATTR(2), /* 110 - n */ 636 TKID_ATTR(1) | TKID_ATTR(2), /* 111 - o */ 637 TKID_ATTR(1) | TKID_ATTR(2), /* 112 - p */ 638 TKID_ATTR(1) | TKID_ATTR(2), /* 113 - q */ 639 TKID_ATTR(1) | TKID_ATTR(2), /* 114 - r */ 640 TKID_ATTR(1) | TKID_ATTR(2), /* 115 - s */ 641 TKID_ATTR(1) | TKID_ATTR(2), /* 116 - t */ 642 TKID_ATTR(1) | TKID_ATTR(2), /* 117 - u */ 643 TKID_ATTR(1) | TKID_ATTR(2), /* 118 - v */ 644 TKID_ATTR(1) | TKID_ATTR(2), /* 119 - w */ 645 TKID_ATTR(1) | TKID_ATTR(2), /* 120 - x */ 646 TKID_ATTR(1) | TKID_ATTR(2), /* 121 - y */ 647 TKID_ATTR(1) | TKID_ATTR(2), /* 122 - z */ 648 TKID_ATTR_CONT(1), /* 123 - { */ 649 TKID_ATTR_CONT(1), /* 124 - | */ 650 TKID_ATTR_CONT(1), /* 125 - } */ 651 TKID_ATTR(1), /* 126 - ~ */ 652 TKID_ATTR_CONT(1), /* 127 - DEL */ 653 }; 654 655 656 /* 657 * Advance the given string pointer to the next newline character, 658 * or the terminating NULL if there is none. 659 */ 660 inline static void 661 advance_to_eol(char **str) 662 { 663 char *s = *str; 664 665 while ((*s != '\n') && (*s != '\0')) 666 s++; 667 *str = s; 668 } 669 670 /* 671 * Insert a NULL patch at the given address 672 */ 673 inline static void 674 null_patch_set(char *str, ld_map_npatch_t *np) 675 { 676 np->np_ptr = str; 677 np->np_ch = *str; 678 *str = '\0'; 679 } 680 681 /* 682 * Undo a NULL patch 683 */ 684 inline static void 685 null_patch_undo(ld_map_npatch_t *np) 686 { 687 *np->np_ptr = np->np_ch; 688 } 689 690 /* 691 * Insert a NULL patch at the end of the line containing str. 692 */ 693 static void 694 null_patch_eol(char *str, ld_map_npatch_t *np) 695 { 696 advance_to_eol(&str); 697 null_patch_set(str, np); 698 } 699 700 /* 701 * Locate the end of an unquoted identifier. 702 * 703 * entry: 704 * mf - Mapfile descriptor, positioned to first character 705 * of identifier. 706 * 707 * exit: 708 * If the item pointed at by mf is not an identifier, returns NULL. 709 * Otherwise, returns pointer to character after the last character 710 * of the identifier. 711 */ 712 inline static char * 713 ident_delimit(Mapfile *mf) 714 { 715 char *str = mf->mf_next; 716 ld_map_npatch_t np; 717 int c = *str++; 718 719 /* If not a valid start character, report the error */ 720 if ((c & 0x80) || !(tkid_attr[c] & mf->mf_tkid_start)) { 721 null_patch_set(str, &np); 722 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), str); 723 null_patch_undo(&np); 724 return (NULL); 725 } 726 727 /* Keep going until we hit a non-continuing character */ 728 for (c = *str; !(c & 0x80) && (tkid_attr[c] & mf->mf_tkid_cont); 729 c = *++str) 730 ; 731 732 return (str); 733 } 734 735 /* 736 * Allocate memory for a stack. 737 * 738 * entry: 739 * stack - Pointer to stack for which memory is required, cast 740 * to the generic stack type. 741 * n_default - Size to use for initial allocation. 742 * elt_size - sizeof(elt), where elt is the actual stack data type. 743 * 744 * exit: 745 * Returns (1) on success. On error (memory allocation), a message 746 * is printed and False (0) is returned. 747 * 748 * note: 749 * The caller casts the pointer to their actual datatype-specific stack 750 * to be a (generic_stack_t *). The C language will give all stack 751 * structs the same size and layout as long as the underlying platform 752 * uses a single integral type for pointers. Hence, this cast is safe, 753 * and lets a generic routine modify data-specific types without being 754 * aware of those types. 755 */ 756 static Boolean 757 stack_resize(generic_stack_t *stack, size_t n_default, size_t elt_size) 758 { 759 size_t new_n_alloc; 760 void *newaddr; 761 762 /* Use initial size first, and double the allocation on each call */ 763 new_n_alloc = (stack->stk_n_alloc == 0) ? 764 n_default : (stack->stk_n_alloc * 2); 765 766 newaddr = libld_realloc(stack->stk_s, new_n_alloc * elt_size); 767 if (newaddr == NULL) 768 return (FALSE); 769 770 stack->stk_s = newaddr; 771 stack->stk_n_alloc = new_n_alloc; 772 return (TRUE); 773 } 774 775 /* 776 * AVL comparison function for cexp_id_node_t items. 777 * 778 * entry: 779 * n1, n2 - pointers to nodes to be compared 780 * 781 * exit: 782 * Returns -1 if (n1 < n2), 0 if they are equal, and 1 if (n1 > n2) 783 */ 784 static int 785 cexp_ident_cmp(const void *n1, const void *n2) 786 { 787 int rc; 788 789 rc = strcmp(((cexp_id_node_t *)n1)->ceid_name, 790 ((cexp_id_node_t *)n2)->ceid_name); 791 792 if (rc > 0) 793 return (1); 794 if (rc < 0) 795 return (-1); 796 return (0); 797 } 798 799 800 /* 801 * Returns True (1) if name is in the conditional expression identifier 802 * AVL tree, and False (0) otherwise. 803 */ 804 static int 805 cexp_ident_test(const char *name) 806 { 807 cexp_id_node_t node; 808 809 node.ceid_name = name; 810 return (avl_find(lms.lms_cexp_id, &node, 0) != NULL); 811 } 812 813 /* 814 * Add a new boolean identifier to the conditional expression identifier 815 * AVL tree. 816 * 817 * entry: 818 * mf - If non-NULL, the mapfile descriptor for the mapfile 819 * containing the $add directive. NULL if this is an 820 * initialization call. 821 * name - Name of identifier. Must point at stable storage that will 822 * not be moved or modified by the caller following this call. 823 * 824 * exit: 825 * On success, True (1) is returned and name has been entered. 826 * On failure, False (0) is returned and an error has been printed. 827 */ 828 static int 829 cexp_ident_add(Mapfile *mf, const char *name) 830 { 831 cexp_id_node_t *node; 832 833 if (mf != NULL) { 834 DBG_CALL(Dbg_map_cexp_id(mf->mf_ofl->ofl_lml, 1, 835 mf->mf_name, mf->mf_lineno, name)); 836 837 /* If is already known, don't do it again */ 838 if (cexp_ident_test(name)) 839 return (1); 840 } 841 842 if ((node = libld_calloc(sizeof (*node), 1)) == NULL) 843 return (0); 844 node->ceid_name = name; 845 avl_add(lms.lms_cexp_id, node); 846 return (1); 847 } 848 849 /* 850 * Remove a boolean identifier from the conditional expression identifier 851 * AVL tree. 852 * 853 * entry: 854 * mf - Mapfile descriptor 855 * name - Name of identifier. 856 * 857 * exit: 858 * If the name was in the tree, it has been removed. If not, 859 * then this routine quietly returns. 860 */ 861 static void 862 cexp_ident_clear(Mapfile *mf, const char *name) 863 { 864 cexp_id_node_t node; 865 cexp_id_node_t *real_node; 866 867 DBG_CALL(Dbg_map_cexp_id(mf->mf_ofl->ofl_lml, 0, 868 mf->mf_name, mf->mf_lineno, name)); 869 870 node.ceid_name = name; 871 real_node = avl_find(lms.lms_cexp_id, &node, 0); 872 if (real_node != NULL) 873 avl_remove(lms.lms_cexp_id, real_node); 874 } 875 876 /* 877 * Initialize the AVL tree that holds the names of the currently defined 878 * boolean identifiers for conditional expressions ($if/$elif). 879 * 880 * entry: 881 * ofl - Output file descriptor 882 * 883 * exit: 884 * On success, TRUE (1) is returned and lms.lms_cexp_id is ready for use. 885 * On failure, FALSE (0) is returned. 886 */ 887 static Boolean 888 cexp_ident_init(void) 889 { 890 /* If already done, use it */ 891 if (lms.lms_cexp_id != NULL) 892 return (TRUE); 893 894 lms.lms_cexp_id = libld_calloc(sizeof (*lms.lms_cexp_id), 1); 895 if (lms.lms_cexp_id == NULL) 896 return (FALSE); 897 avl_create(lms.lms_cexp_id, cexp_ident_cmp, sizeof (cexp_id_node_t), 898 SGSOFFSETOF(cexp_id_node_t, ceid_avlnode)); 899 900 901 /* ELFCLASS */ 902 if (cexp_ident_add(NULL, (ld_targ.t_m.m_class == ELFCLASS32) ? 903 MSG_ORIG(MSG_STR_UELF32) : MSG_ORIG(MSG_STR_UELF64)) == 0) 904 return (FALSE); 905 906 /* Machine */ 907 switch (ld_targ.t_m.m_mach) { 908 case EM_386: 909 case EM_AMD64: 910 if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_UX86)) == 0) 911 return (FALSE); 912 break; 913 914 case EM_SPARC: 915 case EM_SPARCV9: 916 if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_USPARC)) == 0) 917 return (FALSE); 918 break; 919 } 920 921 /* true is always defined */ 922 if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_TRUE)) == 0) 923 return (FALSE); 924 925 return (TRUE); 926 } 927 928 /* 929 * Validate the string starting at mf->mf_next as being a 930 * boolean conditional expression identifier. 931 * 932 * entry: 933 * mf - Mapfile descriptor 934 * len - NULL, or address of variable to receive strlen() of identifier 935 * directive - If (len == NULL), string giving name of directive being 936 * processed. Ignored if (len != NULL). 937 * 938 * exit: 939 * On success: 940 * - If len is NULL, a NULL is inserted following the final 941 * character of the identifier, and the remainder of the string 942 * is tested to ensure it is empty, or only contains whitespace. 943 * - If len is non-NULL, *len is set to the number of characters 944 * in the identifier, and the rest of the string is not modified. 945 * - TRUE (1) is returned 946 * 947 * On failure, returns FALSE (0). 948 */ 949 static Boolean 950 cexp_ident_validate(Mapfile *mf, size_t *len, const char *directive) 951 { 952 char *tail; 953 954 if ((tail = ident_delimit(mf)) == NULL) 955 return (FALSE); 956 957 /* 958 * If len is non-NULL, we simple count the number of characters 959 * consumed by the identifier and are done. If len is NULL, then 960 * ensure there's nothing left but whitespace, and NULL terminate 961 * the identifier to remove it. 962 */ 963 if (len != NULL) { 964 *len = tail - mf->mf_next; 965 } else if (*tail != '\0') { 966 *tail++ = '\0'; 967 while (isspace(*tail)) 968 tail++; 969 if (*tail != '\0') { 970 mf_fatal(mf, MSG_INTL(MSG_MAP_BADEXTRA), directive); 971 return (FALSE); 972 } 973 } 974 975 return (TRUE); 976 } 977 978 /* 979 * Push a new operator onto the conditional expression operator stack. 980 * 981 * entry: 982 * mf - Mapfile descriptor 983 * op - Operator to push 984 * 985 * exit: 986 * On success, TRUE (1) is returned, otherwise FALSE (0). 987 */ 988 static Boolean 989 cexp_push_op(cexp_op_t op) 990 { 991 if (STACK_RESERVE(lms.lms_cexp_op_stack, CEXP_OP_STACK_INIT) == 0) 992 return (FALSE); 993 994 STACK_PUSH(lms.lms_cexp_op_stack) = op; 995 return (TRUE); 996 } 997 998 /* 999 * Evaluate the basic operator (non-paren) at the top of lms.lms_cexp_op_stack, 1000 * and push the results on lms.lms_cexp_val_stack. 1001 * 1002 * exit: 1003 * On success, returns TRUE (1). On error, FALSE (0) is returned, 1004 * and the caller is responsible for issuing the error. 1005 */ 1006 static Boolean 1007 cexp_eval_op(void) 1008 { 1009 cexp_op_t op; 1010 uchar_t val; 1011 1012 op = STACK_POP(lms.lms_cexp_op_stack); 1013 switch (op) { 1014 case CEXP_OP_AND: 1015 if (lms.lms_cexp_val_stack.stk_n < 2) 1016 return (FALSE); 1017 val = STACK_POP(lms.lms_cexp_val_stack); 1018 STACK_TOP(lms.lms_cexp_val_stack) = val && 1019 STACK_TOP(lms.lms_cexp_val_stack); 1020 break; 1021 1022 case CEXP_OP_OR: 1023 if (lms.lms_cexp_val_stack.stk_n < 2) 1024 return (FALSE); 1025 val = STACK_POP(lms.lms_cexp_val_stack); 1026 STACK_TOP(lms.lms_cexp_val_stack) = val || 1027 STACK_TOP(lms.lms_cexp_val_stack); 1028 break; 1029 1030 case CEXP_OP_NEG: 1031 if (lms.lms_cexp_val_stack.stk_n < 1) 1032 return (FALSE); 1033 STACK_TOP(lms.lms_cexp_val_stack) = 1034 !STACK_TOP(lms.lms_cexp_val_stack); 1035 break; 1036 default: 1037 return (FALSE); 1038 } 1039 1040 return (TRUE); 1041 } 1042 1043 /* 1044 * Evaluate an expression for a $if/$elif control directive. 1045 * 1046 * entry: 1047 * mf - Mapfile descriptor for NULL terminated string 1048 * containing the expression. 1049 * 1050 * exit: 1051 * The contents of str are modified by this routine. 1052 * One of the following values are returned: 1053 * -1 Syntax error encountered (an error is printed) 1054 * 0 The expression evaluates to False 1055 * 1 The expression evaluates to True. 1056 * 1057 * note: 1058 * A simplified version of Dijkstra's Shunting Yard algorithm is used 1059 * to convert this syntax into postfix form and then evaluate it. 1060 * Our version has no functions and a tiny set of operators. 1061 * 1062 * The expressions consist of boolean identifiers, which can be 1063 * combined using the following operators, listed from highest 1064 * precedence to least: 1065 * 1066 * Operator Meaning 1067 * ------------------------------------------------- 1068 * (expr) sub-expression, non-associative 1069 * ! logical negation, prefix, left associative 1070 * && || logical and/or, binary, left associative 1071 * 1072 * The operands manipulated by these operators are names, consisting of 1073 * a sequence of letters and digits. The first character must be a letter. 1074 * Underscore (_) and period (.) are also considered to be characters. 1075 * An operand is considered True if it is found in our set of known 1076 * names (lms.lms_cexp_id), and False otherwise. 1077 * 1078 * The Shunting Yard algorithm works using two stacks, one for operators, 1079 * and a second for operands. The infix input expression is tokenized from 1080 * left to right and processed in order. Issues of associativity and 1081 * precedence are managed by reducing (poping and evaluating) items with 1082 * higer precedence before pushing additional tokens with lower precedence. 1083 */ 1084 static int 1085 cexp_eval_expr(Mapfile *mf) 1086 { 1087 char *ident; 1088 size_t len; 1089 cexp_op_t new_op = CEXP_OP_AND; /* to catch binop at start */ 1090 ld_map_npatch_t np; 1091 char *str = mf->mf_next; 1092 1093 STACK_RESET(lms.lms_cexp_op_stack); 1094 STACK_RESET(lms.lms_cexp_val_stack); 1095 1096 for (; *str; str++) { 1097 1098 /* Skip whitespace */ 1099 while (isspace(*str)) 1100 str++; 1101 if (!*str) 1102 break; 1103 1104 switch (*str) { 1105 case '&': 1106 case '|': 1107 if (*(str + 1) != *str) 1108 goto token_error; 1109 if ((new_op != CEXP_OP_NONE) && 1110 (new_op != CEXP_OP_CPAR)) { 1111 mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_BADOPUSE)); 1112 return (-1); 1113 } 1114 str++; 1115 1116 /* 1117 * As this is a left associative binary operator, we 1118 * need to process all operators of equal or higher 1119 * precedence before pushing the new operator. 1120 */ 1121 while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack)) { 1122 cexp_op_t op = STACK_TOP(lms.lms_cexp_op_stack); 1123 1124 1125 if ((op != CEXP_OP_AND) && (op != CEXP_OP_OR) && 1126 (op != CEXP_OP_NEG)) 1127 break; 1128 1129 if (!cexp_eval_op()) 1130 goto semantic_error; 1131 } 1132 1133 new_op = (*str == '&') ? CEXP_OP_AND : CEXP_OP_OR; 1134 if (!cexp_push_op(new_op)) 1135 return (-1); 1136 break; 1137 1138 case '!': 1139 new_op = CEXP_OP_NEG; 1140 if (!cexp_push_op(new_op)) 1141 return (-1); 1142 break; 1143 1144 case '(': 1145 new_op = CEXP_OP_OPAR; 1146 if (!cexp_push_op(new_op)) 1147 return (-1); 1148 break; 1149 1150 case ')': 1151 new_op = CEXP_OP_CPAR; 1152 1153 /* Evaluate the operator stack until reach '(' */ 1154 while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack) && 1155 (STACK_TOP(lms.lms_cexp_op_stack) != CEXP_OP_OPAR)) 1156 if (!cexp_eval_op()) 1157 goto semantic_error; 1158 1159 /* 1160 * If the top of operator stack is not an open paren, 1161 * when we have an error. In this case, the operator 1162 * stack will be empty due to the loop above. 1163 */ 1164 if (STACK_IS_EMPTY(lms.lms_cexp_op_stack)) 1165 goto unbalpar_error; 1166 lms.lms_cexp_op_stack.stk_n--; /* Pop OPAR */ 1167 break; 1168 1169 default: 1170 /* Ensure there's room to push another operand */ 1171 if (STACK_RESERVE(lms.lms_cexp_val_stack, 1172 CEXP_VAL_STACK_INIT) == 0) 1173 return (0); 1174 new_op = CEXP_OP_NONE; 1175 1176 /* 1177 * Operands cannot be numbers. However, we accept two 1178 * special cases: '0' means false, and '1' is true. 1179 * This is done to support the common C idiom of 1180 * '#if 1' and '#if 0' to conditionalize code under 1181 * development. 1182 */ 1183 if ((*str == '0') || (*str == '1')) { 1184 STACK_PUSH(lms.lms_cexp_val_stack) = 1185 (*str == '1'); 1186 break; 1187 } 1188 1189 /* Look up the identifier */ 1190 ident = mf->mf_next = str; 1191 if (!cexp_ident_validate(mf, &len, NULL)) 1192 return (-1); 1193 str += len - 1; /* loop will advance past final ch */ 1194 null_patch_set(&ident[len], &np); 1195 STACK_PUSH(lms.lms_cexp_val_stack) = 1196 cexp_ident_test(ident); 1197 null_patch_undo(&np); 1198 1199 break; 1200 } 1201 } 1202 1203 /* Evaluate the operator stack until empty */ 1204 while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack)) { 1205 if (STACK_TOP(lms.lms_cexp_op_stack) == CEXP_OP_OPAR) 1206 goto unbalpar_error; 1207 1208 if (!cexp_eval_op()) 1209 goto semantic_error; 1210 } 1211 1212 /* There should be exactly one value left */ 1213 if (lms.lms_cexp_val_stack.stk_n != 1) 1214 goto semantic_error; 1215 1216 /* Final value is the result */ 1217 return (lms.lms_cexp_val_stack.stk_s[0]); 1218 1219 /* Errors issued more than once are handled below, accessed via goto */ 1220 1221 token_error: /* unexpected characters in input stream */ 1222 mf_fatal(mf, MSG_INTL(MSG_MAP_CEXP_TOKERR), str); 1223 return (-1); 1224 1225 semantic_error: /* valid tokens, but in invalid arrangement */ 1226 mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_SEMERR)); 1227 return (-1); 1228 1229 unbalpar_error: /* Extra or missing parenthesis */ 1230 mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_UNBALPAR)); 1231 return (-1); 1232 } 1233 1234 /* 1235 * Process a mapfile control directive. These directives start with 1236 * the dollar character, and are used to manage details of the mapfile 1237 * itself, such as version and conditional input. 1238 * 1239 * entry: 1240 * mf - Mapfile descriptor 1241 * 1242 * exit: 1243 * Returns TRUE (1) for success, and FALSE (0) on error. In the 1244 * error case, a descriptive error is issued. 1245 */ 1246 static Boolean 1247 cdir_process(Mapfile *mf) 1248 { 1249 typedef enum { /* Directive types */ 1250 CDIR_T_UNKNOWN = 0, /* Unrecognized control directive */ 1251 CDIR_T_ADD, /* $add */ 1252 CDIR_T_CLEAR, /* $clear */ 1253 CDIR_T_ERROR, /* $error */ 1254 CDIR_T_VERSION, /* $mapfile_version */ 1255 CDIR_T_IF, /* $if */ 1256 CDIR_T_ELIF, /* $elif */ 1257 CDIR_T_ELSE, /* $else */ 1258 CDIR_T_ENDIF, /* $endif */ 1259 } cdir_t; 1260 1261 typedef enum { /* Types of arguments accepted by directives */ 1262 ARG_T_NONE, /* Directive takes no arguments */ 1263 ARG_T_EXPR, /* Directive takes a conditional expression */ 1264 ARG_T_ID, /* Conditional expression identifier */ 1265 ARG_T_STR, /* Non-empty string */ 1266 ARG_T_IGN /* Ignore the argument */ 1267 } cdir_arg_t; 1268 1269 typedef struct { 1270 const char *md_name; /* Directive name */ 1271 size_t md_size; /* strlen(md_name) */ 1272 cdir_arg_t md_arg; /* Type of arguments */ 1273 cdir_t md_op; /* CDIR_T_ code */ 1274 } cdir_match_t; 1275 1276 /* Control Directives: The most likely items are listed first */ 1277 static cdir_match_t match_data[] = { 1278 { MSG_ORIG(MSG_STR_CDIR_IF), MSG_STR_CDIR_IF_SIZE, 1279 ARG_T_EXPR, CDIR_T_IF }, 1280 { MSG_ORIG(MSG_STR_CDIR_ENDIF), MSG_STR_CDIR_ENDIF_SIZE, 1281 ARG_T_NONE, CDIR_T_ENDIF }, 1282 { MSG_ORIG(MSG_STR_CDIR_ELSE), MSG_STR_CDIR_ELSE_SIZE, 1283 ARG_T_NONE, CDIR_T_ELSE }, 1284 { MSG_ORIG(MSG_STR_CDIR_ELIF), MSG_STR_CDIR_ELIF_SIZE, 1285 ARG_T_EXPR, CDIR_T_ELIF }, 1286 { MSG_ORIG(MSG_STR_CDIR_ERROR), MSG_STR_CDIR_ERROR_SIZE, 1287 ARG_T_STR, CDIR_T_ERROR }, 1288 { MSG_ORIG(MSG_STR_CDIR_ADD), MSG_STR_CDIR_ADD_SIZE, 1289 ARG_T_ID, CDIR_T_ADD }, 1290 { MSG_ORIG(MSG_STR_CDIR_CLEAR), MSG_STR_CDIR_CLEAR_SIZE, 1291 ARG_T_ID, CDIR_T_CLEAR }, 1292 { MSG_ORIG(MSG_STR_CDIR_MFVER), MSG_STR_CDIR_MFVER_SIZE, 1293 ARG_T_IGN, CDIR_T_VERSION }, 1294 1295 { NULL, 0, 1296 ARG_T_IGN, CDIR_T_UNKNOWN } 1297 }; 1298 1299 cdir_match_t *mdptr; 1300 char *tail; 1301 int expr_eval; /* Result of evaluating ARG_T_EXPR */ 1302 Mapfile arg_mf; 1303 cdir_level_t *level; 1304 int pass, parent_pass; /* Currently accepting input */ 1305 1306 restart: 1307 /* Is the immediate context passing input? */ 1308 pass = STACK_IS_EMPTY(lms.lms_cdir_stack) || 1309 STACK_TOP(lms.lms_cdir_stack).cdl_pass; 1310 1311 /* Is the surrounding (parent) context passing input? */ 1312 parent_pass = (lms.lms_cdir_stack.stk_n <= 1) || 1313 lms.lms_cdir_stack.stk_s[lms.lms_cdir_stack.stk_n - 2].cdl_pass; 1314 1315 1316 for (mdptr = match_data; mdptr->md_name; mdptr++) { 1317 /* Prefix must match, or we move on */ 1318 if (strncmp(mf->mf_next, mdptr->md_name, 1319 mdptr->md_size) != 0) 1320 continue; 1321 tail = mf->mf_next + mdptr->md_size; 1322 1323 /* 1324 * If there isn't whitespace, or a NULL terminator following 1325 * the prefix, then even though our prefix matched, the actual 1326 * token is longer, and we don't have a match. 1327 */ 1328 if (!isspace(*tail) && (*tail != '\0')) 1329 continue; 1330 1331 /* We have matched a valid control directive */ 1332 break; 1333 } 1334 1335 /* Advance input to end of the current line */ 1336 advance_to_eol(&mf->mf_next); 1337 1338 /* 1339 * Set up a temporary mapfile descriptor to reference the 1340 * argument string. The benefit of this second block, is that 1341 * we can advance the real one to the next line now, which allows 1342 * us to return at any time knowing that the input has been moved 1343 * to the proper spot. This simplifies the error cases. 1344 * 1345 * If we had a match, tail points at the start of the string. 1346 * Otherwise, we want to point at the end of the line. 1347 */ 1348 arg_mf = *mf; 1349 if (mdptr->md_name == NULL) 1350 arg_mf.mf_text = arg_mf.mf_next; 1351 else 1352 arg_mf.mf_text = arg_mf.mf_next = tail; 1353 1354 /* 1355 * Null terminate the arguments, and advance the main mapfile 1356 * state block to the next line. 1357 */ 1358 if (*mf->mf_next == '\n') { 1359 *mf->mf_next++ = '\0'; 1360 mf->mf_lineno++; 1361 } 1362 1363 /* Skip leading whitespace to arguments */ 1364 while (isspace(*arg_mf.mf_next)) 1365 arg_mf.mf_next++; 1366 1367 /* Strip off any comment present on the line */ 1368 for (tail = arg_mf.mf_next; *tail; tail++) 1369 if (*tail == '#') { 1370 *tail = '\0'; 1371 break; 1372 } 1373 1374 /* 1375 * Process the arguments as necessary depending on their type. 1376 * If this control directive is nested inside a surrounding context 1377 * that is not currently passing text, then we skip the argument 1378 * evaluation. This follows the behavior of the C preprocessor, 1379 * which only examines enough to detect the operation within 1380 * a disabled section, without issuing errors about the arguments. 1381 */ 1382 if (pass || (parent_pass && (mdptr->md_op == CDIR_T_ELIF))) { 1383 switch (mdptr->md_arg) { 1384 case ARG_T_NONE: 1385 if (*arg_mf.mf_next == '\0') 1386 break; 1387 /* Args are present, but not wanted */ 1388 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REQNOARG), 1389 mdptr->md_name); 1390 return (FALSE); 1391 1392 case ARG_T_EXPR: 1393 /* Ensure that arguments are present */ 1394 if (*arg_mf.mf_next == '\0') 1395 goto error_reqarg; 1396 expr_eval = cexp_eval_expr(&arg_mf); 1397 if (expr_eval == -1) 1398 return (FALSE); 1399 break; 1400 1401 case ARG_T_ID: 1402 /* Ensure that arguments are present */ 1403 if (*arg_mf.mf_next == '\0') 1404 goto error_reqarg; 1405 if (!cexp_ident_validate(&arg_mf, NULL, 1406 mdptr->md_name)) 1407 return (FALSE); 1408 break; 1409 1410 case ARG_T_STR: 1411 /* Ensure that arguments are present */ 1412 if (*arg_mf.mf_next == '\0') 1413 goto error_reqarg; 1414 /* Remove trailing whitespace */ 1415 tail = arg_mf.mf_next + strlen(arg_mf.mf_next); 1416 while ((tail > arg_mf.mf_next) && 1417 isspace(*(tail -1))) 1418 tail--; 1419 *tail = '\0'; 1420 break; 1421 } 1422 } 1423 1424 /* 1425 * Carry out the specified control directive: 1426 */ 1427 if (!STACK_IS_EMPTY(lms.lms_cdir_stack)) 1428 level = &STACK_TOP(lms.lms_cdir_stack); 1429 1430 switch (mdptr->md_op) { 1431 case CDIR_T_UNKNOWN: /* Unrecognized control directive */ 1432 if (!pass) 1433 break; 1434 mf_fatal0(&arg_mf, MSG_INTL(MSG_MAP_CDIR_BAD)); 1435 return (FALSE); 1436 1437 case CDIR_T_ADD: 1438 if (pass && !cexp_ident_add(&arg_mf, arg_mf.mf_next)) 1439 return (FALSE); 1440 break; 1441 1442 case CDIR_T_CLEAR: 1443 if (pass) 1444 cexp_ident_clear(&arg_mf, arg_mf.mf_next); 1445 break; 1446 1447 case CDIR_T_ERROR: 1448 if (!pass) 1449 break; 1450 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ERROR), 1451 arg_mf.mf_next); 1452 return (FALSE); 1453 1454 case CDIR_T_VERSION: 1455 /* 1456 * A $mapfile_version control directive can only appear 1457 * as the first directive in a mapfile, and is used to 1458 * determine the syntax for the rest of the file. It's 1459 * too late to be using it here. 1460 */ 1461 if (!pass) 1462 break; 1463 mf_fatal0(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REPVER)); 1464 return (FALSE); 1465 1466 case CDIR_T_IF: 1467 /* Push a new level on the conditional input stack */ 1468 if (STACK_RESERVE(lms.lms_cdir_stack, CDIR_STACK_INIT) == 0) 1469 return (FALSE); 1470 level = &lms.lms_cdir_stack.stk_s[lms.lms_cdir_stack.stk_n++]; 1471 level->cdl_if_lineno = arg_mf.mf_lineno; 1472 level->cdl_else_lineno = 0; 1473 1474 /* 1475 * If previous level is not passing, this level is disabled. 1476 * Otherwise, the expression value determines what happens. 1477 */ 1478 if (pass) { 1479 level->cdl_done = level->cdl_pass = expr_eval; 1480 } else { 1481 level->cdl_done = 1; 1482 level->cdl_pass = 0; 1483 } 1484 break; 1485 1486 case CDIR_T_ELIF: 1487 /* $elif requires an open $if construct */ 1488 if (STACK_IS_EMPTY(lms.lms_cdir_stack)) { 1489 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF), 1490 MSG_ORIG(MSG_STR_CDIR_ELIF)); 1491 return (FALSE); 1492 } 1493 1494 /* $elif cannot follow $else */ 1495 if (level->cdl_else_lineno > 0) { 1496 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ELSE), 1497 MSG_ORIG(MSG_STR_CDIR_ELIF), 1498 EC_LINENO(level->cdl_else_lineno)); 1499 return (FALSE); 1500 } 1501 1502 /* 1503 * Accept text from $elif if the level isn't already 1504 * done and the expression evaluates to true. 1505 */ 1506 level->cdl_pass = !level->cdl_done && expr_eval; 1507 if (level->cdl_pass) 1508 level->cdl_done = 1; 1509 break; 1510 1511 case CDIR_T_ELSE: 1512 /* $else requires an open $if construct */ 1513 if (STACK_IS_EMPTY(lms.lms_cdir_stack)) { 1514 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF), 1515 MSG_ORIG(MSG_STR_CDIR_ELSE)); 1516 return (FALSE); 1517 } 1518 1519 /* There can only be one $else in the chain */ 1520 if (level->cdl_else_lineno > 0) { 1521 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ELSE), 1522 MSG_ORIG(MSG_STR_CDIR_ELSE), 1523 EC_LINENO(level->cdl_else_lineno)); 1524 return (FALSE); 1525 } 1526 level->cdl_else_lineno = arg_mf.mf_lineno; 1527 1528 /* Accept text from $else if the level isn't already done */ 1529 level->cdl_pass = !level->cdl_done; 1530 level->cdl_done = 1; 1531 break; 1532 1533 case CDIR_T_ENDIF: 1534 /* $endif requires an open $if construct */ 1535 if (STACK_IS_EMPTY(lms.lms_cdir_stack)) { 1536 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF), 1537 MSG_ORIG(MSG_STR_CDIR_ENDIF)); 1538 return (FALSE); 1539 } 1540 if (--lms.lms_cdir_stack.stk_n > 0) 1541 level = &STACK_TOP(lms.lms_cdir_stack); 1542 break; 1543 1544 default: 1545 return (FALSE); 1546 } 1547 1548 /* Evaluating the control directive above can change pass status */ 1549 expr_eval = STACK_IS_EMPTY(lms.lms_cdir_stack) || 1550 STACK_TOP(lms.lms_cdir_stack).cdl_pass; 1551 if (expr_eval != pass) { 1552 pass = expr_eval; 1553 DBG_CALL(Dbg_map_pass(arg_mf.mf_ofl->ofl_lml, pass, 1554 arg_mf.mf_name, arg_mf.mf_lineno, mdptr->md_name)); 1555 } 1556 1557 /* 1558 * At this point, we have processed a control directive, 1559 * updated our conditional state stack, and the input is 1560 * positioned at the start of the line following the directive. 1561 * If the current level is accepting input, then give control 1562 * back to ld_map_gettoken() to resume its normal operation. 1563 */ 1564 if (pass) 1565 return (TRUE); 1566 1567 /* 1568 * The current level is not accepting input. Only another 1569 * control directive can change this, so read and discard input 1570 * until we encounter one of the following: 1571 * 1572 * EOF: Return and let ld_map_gettoken() report it 1573 * Control Directive: Restart this function / evaluate new directive 1574 */ 1575 while (*mf->mf_next != '\0') { 1576 /* Skip leading whitespace */ 1577 while (isspace_nonl(*mf->mf_next)) 1578 mf->mf_next++; 1579 1580 /* 1581 * Control directives start with a '$'. If we hit 1582 * one, restart the function at this point 1583 */ 1584 if (*mf->mf_next == '$') 1585 goto restart; 1586 1587 /* Not a control directive, so advance input to next line */ 1588 advance_to_eol(&mf->mf_next); 1589 if (*mf->mf_next == '\n') { 1590 mf->mf_lineno++; 1591 mf->mf_next++; 1592 } 1593 } 1594 1595 assert(*mf->mf_next == '\0'); 1596 return (TRUE); 1597 1598 /* 1599 * Control directives that require an argument that is not present 1600 * jump here to report the error and exit. 1601 */ 1602 error_reqarg: 1603 mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REQARG), mdptr->md_name); 1604 return (FALSE); 1605 1606 } 1607 1608 #ifndef _ELF64 1609 /* 1610 * Convert a string to lowercase. 1611 */ 1612 void 1613 ld_map_lowercase(char *str) 1614 { 1615 while (*str = tolower(*str)) 1616 str++; 1617 } 1618 #endif 1619 1620 /* 1621 * Wrappper on strtoul()/strtoull(), adapted to return an Xword. 1622 * 1623 * entry: 1624 * str - Pointer to string to be converted. 1625 * endptr - As documented for strtoul(3C). Either NULL, or 1626 * address of pointer to receive the address of the first 1627 * unused character in str (called "final" in strtoul(3C)). 1628 * ret_value - Address of Xword variable to receive result. 1629 * 1630 * exit: 1631 * On success, *ret_value receives the result, *endptr is updated if 1632 * endptr is non-NULL, and STRTOXWORD_OK is returned. 1633 * On failure, STRTOXWORD_TOBIG is returned if an otherwise valid 1634 * value was too large, and STRTOXWORD_BAD is returned if the string 1635 * is malformed. 1636 */ 1637 ld_map_strtoxword_t 1638 ld_map_strtoxword(const char *restrict str, char **restrict endptr, 1639 Xword *ret_value) 1640 { 1641 #if defined(_ELF64) /* _ELF64 */ 1642 #define FUNC strtoull /* Function to use */ 1643 #define FUNC_MAX ULLONG_MAX /* Largest value returned by FUNC */ 1644 #define XWORD_MAX ULLONG_MAX /* Largest Xword value */ 1645 uint64_t value; /* Variable of FUNC return type */ 1646 #else /* _ELF32 */ 1647 #define FUNC strtoul 1648 #define FUNC_MAX ULONG_MAX 1649 #define XWORD_MAX UINT_MAX 1650 ulong_t value; 1651 #endif 1652 1653 char *endptr_local; /* Used if endptr is NULL */ 1654 1655 if (endptr == NULL) 1656 endptr = &endptr_local; 1657 1658 errno = 0; 1659 value = FUNC(str, endptr, 0); 1660 if ((errno != 0) || (str == *endptr)) { 1661 if (value == FUNC_MAX) 1662 return (STRTOXWORD_TOOBIG); 1663 else 1664 return (STRTOXWORD_BAD); 1665 } 1666 1667 /* 1668 * If this is a 64-bit linker building an ELFCLASS32 object, 1669 * the FUNC return type is a 64-bit value, while an Xword is 1670 * 32-bit. It is possible for FUNC to be able to convert a value 1671 * too large for our return type. 1672 */ 1673 #if FUNC_MAX != XWORD_MAX 1674 if (value > XWORD_MAX) 1675 return (STRTOXWORD_TOOBIG); 1676 #endif 1677 1678 *ret_value = value; 1679 return (STRTOXWORD_OK); 1680 1681 #undef FUNC 1682 #undef FUNC_MAX 1683 #undef XWORD_MAC 1684 } 1685 1686 /* 1687 * Convert the unsigned integer value at the current mapfile input 1688 * into binary form. All numeric values in mapfiles are treated as 1689 * unsigned integers of the appropriate width for an address on the 1690 * given target. Values can be decimal, hex, or octal. 1691 * 1692 * entry: 1693 * str - String to process. 1694 * value - Address of variable to receive resulting value. 1695 * notail - If TRUE, an error is issued if non-whitespace 1696 * characters other than '#' (comment) are found following 1697 * the numeric value before the end of line. 1698 * 1699 * exit: 1700 * On success: 1701 * - *str is advanced to the next character following the value 1702 * - *value receives the value 1703 * - Returns TRUE (1). 1704 * On failure, returns FALSE (0). 1705 */ 1706 static Boolean 1707 ld_map_getint(Mapfile *mf, ld_map_tkval_t *value, Boolean notail) 1708 { 1709 ld_map_strtoxword_t s2xw_ret; 1710 ld_map_npatch_t np; 1711 char *endptr; 1712 char *errstr = mf->mf_next; 1713 1714 value->tkv_int.tkvi_str = mf->mf_next; 1715 s2xw_ret = ld_map_strtoxword(mf->mf_next, &endptr, 1716 &value->tkv_int.tkvi_value); 1717 if (s2xw_ret != STRTOXWORD_OK) { 1718 null_patch_eol(mf->mf_next, &np); 1719 if (s2xw_ret == STRTOXWORD_TOOBIG) 1720 mf_fatal(mf, MSG_INTL(MSG_MAP_VALUELIMIT), errstr); 1721 else 1722 mf_fatal(mf, MSG_INTL(MSG_MAP_MALVALUE), errstr); 1723 null_patch_undo(&np); 1724 return (FALSE); 1725 } 1726 1727 /* Advance position to item following value, skipping whitespace */ 1728 value->tkv_int.tkvi_cnt = endptr - mf->mf_next; 1729 mf->mf_next = endptr; 1730 while (isspace_nonl(*mf->mf_next)) 1731 mf->mf_next++; 1732 1733 /* If requested, ensure there's nothing left */ 1734 if (notail && (*mf->mf_next != '\n') && (*mf->mf_next != '#') && 1735 (*mf->mf_next != '\0')) { 1736 null_patch_eol(mf->mf_next, &np); 1737 mf_fatal(mf, MSG_INTL(MSG_MAP_BADVALUETAIL), errstr); 1738 null_patch_undo(&np); 1739 return (FALSE); 1740 } 1741 1742 return (TRUE); 1743 } 1744 1745 /* 1746 * Convert a an unquoted identifier into a TK_STRING token, using the 1747 * rules for syntax version in use. Used exclusively by ld_map_gettoken(). 1748 * 1749 * entry: 1750 * mf - Mapfile descriptor, positioned to the first character of 1751 * the string. 1752 * flags - Bitmask of options to control ld_map_gettoken()s behavior 1753 * tkv- Address of pointer to variable to receive token value. 1754 * 1755 * exit: 1756 * On success, mf is advanced past the token, tkv is updated with 1757 * the string, and TK_STRING is returned. On error, TK_ERROR is returned. 1758 */ 1759 inline static Token 1760 gettoken_ident(Mapfile *mf, int flags, ld_map_tkval_t *tkv) 1761 { 1762 char *end; 1763 Token tok; 1764 ld_map_npatch_t np; 1765 1766 tkv->tkv_str = mf->mf_next; 1767 if ((end = ident_delimit(mf)) == NULL) 1768 return (TK_ERROR); 1769 mf->mf_next = end; 1770 1771 /* 1772 * One advantage of reading the entire mapfile into memory is that 1773 * we can access the strings within it without having to allocate 1774 * more memory or make copies. In order to do that, we need to NULL 1775 * terminate this identifier. That is going to overwrite the 1776 * following character. The problem this presents is that the next 1777 * character may well be the first character of a subsequent token. 1778 * The solution to this is: 1779 * 1780 * 1) Disallow the case where the next character is able to 1781 * start a string. This is not legal mapfile syntax anyway, 1782 * so catching it here simplifies matters. 1783 * 2) Copy the character into the special mf->mf_next_ch 1784 * 3) The next call to ld_map_gettoken() checks mf->mf_next_ch, 1785 * and if it is non-0, uses it instead of dereferencing the 1786 * mf_next pointer. 1787 */ 1788 tok = (*mf->mf_next & 0x80) ? 1789 TK_OP_ILLCHR : mf->mf_tokdisp[*mf->mf_next]; 1790 switch (tok) { 1791 case TK_OP_BADCHR: 1792 null_patch_eol(mf->mf_next, &np); 1793 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), mf->mf_next); 1794 null_patch_undo(&np); 1795 return (TK_ERROR); 1796 1797 case TK_OP_SIMQUOTE: 1798 case TK_OP_CQUOTE: 1799 case TK_OP_CDIR: 1800 case TK_OP_NUM: 1801 case TK_OP_ID: 1802 null_patch_eol(mf->mf_next, &np); 1803 mf_fatal(mf, MSG_INTL(MSG_MAP_WSNEEDED), mf->mf_next); 1804 null_patch_undo(&np); 1805 return (TK_ERROR); 1806 } 1807 1808 /* Null terminate, saving the replaced character */ 1809 mf->mf_next_ch = *mf->mf_next; 1810 *mf->mf_next = '\0'; 1811 1812 if (flags & TK_F_STRLC) 1813 ld_map_lowercase(tkv->tkv_str); 1814 return (TK_STRING); 1815 } 1816 1817 /* 1818 * Convert a quoted string into a TK_STRING token, using simple 1819 * quoting rules: 1820 * - Start and end quotes must be present and match 1821 * - There are no special characters or escape sequences. 1822 * This function is used exclusively by ld_map_gettoken(). 1823 * 1824 * entry: 1825 * mf - Mapfile descriptor, positioned to the opening quote character. 1826 * flags - Bitmask of options to control ld_map_gettoken()s behavior 1827 * tkv- Address of pointer to variable to receive token value. 1828 * 1829 * exit: 1830 * On success, mf is advanced past the token, tkv is updated with 1831 * the string, and TK_STRING is returned. On error, TK_ERROR is returned. 1832 */ 1833 inline static Token 1834 gettoken_simquote_str(Mapfile *mf, int flags, ld_map_tkval_t *tkv) 1835 { 1836 char *str, *end; 1837 char quote; 1838 1839 str = mf->mf_next++; 1840 quote = *str; 1841 end = mf->mf_next; 1842 while ((*end != '\0') && (*end != '\n') && (*end != quote)) 1843 end++; 1844 if (*end != quote) { 1845 ld_map_npatch_t np; 1846 1847 null_patch_eol(end, &np); 1848 mf_fatal(mf, MSG_INTL(MSG_MAP_NOTERM), str); 1849 null_patch_undo(&np); 1850 return (TK_ERROR); 1851 } 1852 1853 /* 1854 * end is pointing at the closing quote. We can turn that into NULL 1855 * termination for the string without needing to restore it later. 1856 */ 1857 *end = '\0'; 1858 mf->mf_next = end + 1; 1859 tkv->tkv_str = str + 1; /* Skip opening quote */ 1860 if (flags & TK_F_STRLC) 1861 ld_map_lowercase(tkv->tkv_str); 1862 return (TK_STRING); 1863 } 1864 1865 /* 1866 * Convert a quoted string into a TK_STRING token, using C string literal 1867 * quoting rules: 1868 * - Start and end quotes must be present and match 1869 * - Backslash is an escape, used to introduce special characters 1870 * This function is used exclusively by ld_map_gettoken(). 1871 * 1872 * entry: 1873 * mf - Mapfile descriptor, positioned to the opening quote character. 1874 * flags - Bitmask of options to control ld_map_gettoken()s behavior 1875 * tkv- Address of pointer to variable to receive token value. 1876 * 1877 * exit: 1878 * On success, mf is advanced past the token, tkv is updated with 1879 * the string, and TK_STRING is returned. On error, TK_ERROR is returned. 1880 */ 1881 inline static Token 1882 gettoken_cquote_str(Mapfile *mf, int flags, ld_map_tkval_t *tkv) 1883 { 1884 char *str, *cur, *end; 1885 char quote; 1886 int c; 1887 1888 /* 1889 * This function goes through the quoted string and copies 1890 * it on top of itself, replacing escape sequences with the 1891 * characters they denote. There is always enough room for this, 1892 * because escapes are multi-character sequences that are converted 1893 * to single character results. 1894 */ 1895 str = mf->mf_next++; 1896 quote = *str; 1897 cur = end = mf->mf_next; 1898 for (c = *end++; (c != '\0') && (c != '\n') && (c != quote); 1899 c = *end++) { 1900 if (c == '\\') { 1901 c = conv_translate_c_esc(&end); 1902 if (c == -1) { 1903 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCESC), *end); 1904 return (TK_ERROR); 1905 } 1906 } 1907 *cur++ = c; 1908 } 1909 *cur = '\0'; /* terminate the result */ 1910 if (c != quote) { 1911 ld_map_npatch_t np; 1912 1913 null_patch_eol(end, &np); 1914 mf_fatal(mf, MSG_INTL(MSG_MAP_NOTERM), str); 1915 null_patch_undo(&np); 1916 return (TK_ERROR); 1917 } 1918 1919 /* end is pointing one character past the closing quote */ 1920 mf->mf_next = end; 1921 tkv->tkv_str = str + 1; /* Skip opening quote */ 1922 if (flags & TK_F_STRLC) 1923 ld_map_lowercase(tkv->tkv_str); 1924 return (TK_STRING); 1925 } 1926 1927 /* 1928 * Get a token from the mapfile. 1929 * 1930 * entry: 1931 * mf - Mapfile descriptor 1932 * flags - Bitmask of options to control ld_map_gettoken()s behavior 1933 * tkv- Address of pointer to variable to receive token value. 1934 * 1935 * exit: 1936 * Returns one of the TK_* values, to report the result. If the resulting 1937 * token has a value (TK_STRING / TK_INT), and tkv is non-NULL, tkv 1938 * is filled in with the resulting value. 1939 */ 1940 Token 1941 ld_map_gettoken(Mapfile *mf, int flags, ld_map_tkval_t *tkv) 1942 { 1943 int cdir_allow, ch; 1944 Token tok; 1945 ld_map_npatch_t np; 1946 1947 /* 1948 * Mapfile control directives all start with a '$' character. However, 1949 * they are only valid when they are the first thing on a line. That 1950 * happens on the first call to ld_map_gettoken() for a new a new 1951 * mapfile, as tracked with lms.lms_cdir_valid, and immediately 1952 * following each newline seen in the file. 1953 */ 1954 cdir_allow = lms.lms_cdir_valid; 1955 lms.lms_cdir_valid = 0; 1956 1957 /* Cycle through the characters looking for tokens. */ 1958 for (;;) { 1959 /* 1960 * Process the next character. This is normally *mf->mf_next, 1961 * but if mf->mf_next_ch is non-0, then it contains the 1962 * character, and *mf->mf_next contains a NULL termination 1963 * from the TK_STRING token returned on the previous call. 1964 * 1965 * gettoken_ident() ensures that this is never done to 1966 * a character that starts a string. 1967 */ 1968 if (mf->mf_next_ch == 0) { 1969 ch = *mf->mf_next; 1970 } else { 1971 ch = mf->mf_next_ch; 1972 mf->mf_next_ch = 0; /* Reset */ 1973 } 1974 1975 /* Map the character to a dispatch action */ 1976 tok = (ch & 0x80) ? TK_OP_ILLCHR : mf->mf_tokdisp[ch]; 1977 1978 /* 1979 * Items that require processing are identified as OP tokens. 1980 * We process them, and return a result non-OP token. 1981 * 1982 * Non-OP tokens are single character tokens, and we return 1983 * them immediately. 1984 */ 1985 switch (tok) { 1986 case TK_OP_EOF: 1987 /* If EOFOK is set, quietly report it as TK_EOF */ 1988 if ((flags & TK_F_EOFOK) != 0) 1989 return (TK_EOF); 1990 1991 /* Treat it as a standard error */ 1992 mf_fatal0(mf, MSG_INTL(MSG_MAP_PREMEOF)); 1993 return (TK_ERROR); 1994 1995 case TK_OP_ILLCHR: 1996 mf_fatal(mf, MSG_INTL(MSG_MAP_ILLCHAR), ch); 1997 mf->mf_next++; 1998 return (TK_ERROR); 1999 2000 case TK_OP_BADCHR: 2001 tk_op_badchr: 2002 null_patch_eol(mf->mf_next, &np); 2003 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), mf->mf_next); 2004 null_patch_undo(&np); 2005 mf->mf_next++; 2006 return (TK_ERROR); 2007 2008 case TK_OP_WS: /* White space */ 2009 mf->mf_next++; 2010 break; 2011 2012 case TK_OP_NL: /* White space too, but bump line number. */ 2013 mf->mf_next++; 2014 mf->mf_lineno++; 2015 cdir_allow = 1; 2016 break; 2017 2018 case TK_OP_SIMQUOTE: 2019 if (flags & TK_F_KEYWORD) 2020 goto tk_op_badkwquote; 2021 return (gettoken_simquote_str(mf, flags, tkv)); 2022 2023 case TK_OP_CQUOTE: 2024 if (flags & TK_F_KEYWORD) { 2025 tk_op_badkwquote: 2026 null_patch_eol(mf->mf_next, &np); 2027 mf_fatal(mf, MSG_INTL(MSG_MAP_BADKWQUOTE), 2028 mf->mf_next); 2029 null_patch_undo(&np); 2030 mf->mf_next++; 2031 return (TK_ERROR); 2032 } 2033 return (gettoken_cquote_str(mf, flags, tkv)); 2034 2035 case TK_OP_CMT: 2036 advance_to_eol(&mf->mf_next); 2037 break; 2038 2039 case TK_OP_CDIR: 2040 /* 2041 * Control directives are only valid at the start 2042 * of a line. 2043 */ 2044 if (!cdir_allow) { 2045 null_patch_eol(mf->mf_next, &np); 2046 mf_fatal(mf, MSG_INTL(MSG_MAP_CDIR_NOTBOL), 2047 mf->mf_next); 2048 null_patch_undo(&np); 2049 mf->mf_next++; 2050 return (TK_ERROR); 2051 } 2052 if (!cdir_process(mf)) 2053 return (TK_ERROR); 2054 break; 2055 2056 case TK_OP_NUM: /* Decimal, hex(0x...), or octal (0...) value */ 2057 if (!ld_map_getint(mf, tkv, FALSE)) 2058 return (TK_ERROR); 2059 return (TK_INT); 2060 2061 case TK_OP_ID: /* Unquoted identifier */ 2062 return (gettoken_ident(mf, flags, tkv)); 2063 2064 case TK_OP_CEQUAL: /* += or -= */ 2065 if (*(mf->mf_next + 1) != '=') 2066 goto tk_op_badchr; 2067 tok = (ch == '+') ? TK_PLUSEQ : TK_MINUSEQ; 2068 mf->mf_next += 2; 2069 return (tok); 2070 2071 default: /* Non-OP token */ 2072 mf->mf_next++; 2073 return (tok); 2074 } 2075 } 2076 2077 /*NOTREACHED*/ 2078 assert(0); 2079 return (TK_ERROR); 2080 } 2081 2082 /* 2083 * Given a token and value returned by ld_map_gettoken(), return a string 2084 * representation of it suitable for use in an error message. 2085 * 2086 * entry: 2087 * tok - Token code. Must not be an OP-token 2088 * tkv - Token value 2089 */ 2090 const char * 2091 ld_map_tokenstr(Token tok, ld_map_tkval_t *tkv, Conv_inv_buf_t *inv_buf) 2092 { 2093 size_t cnt; 2094 2095 switch (tok) { 2096 case TK_ERROR: 2097 return (MSG_ORIG(MSG_STR_ERROR)); 2098 case TK_EOF: 2099 return (MSG_ORIG(MSG_STR_EOF)); 2100 case TK_STRING: 2101 return (tkv->tkv_str); 2102 case TK_COLON: 2103 return (MSG_ORIG(MSG_QSTR_COLON)); 2104 case TK_SEMICOLON: 2105 return (MSG_ORIG(MSG_QSTR_SEMICOLON)); 2106 case TK_EQUAL: 2107 return (MSG_ORIG(MSG_QSTR_EQUAL)); 2108 case TK_PLUSEQ: 2109 return (MSG_ORIG(MSG_QSTR_PLUSEQ)); 2110 case TK_MINUSEQ: 2111 return (MSG_ORIG(MSG_QSTR_MINUSEQ)); 2112 case TK_ATSIGN: 2113 return (MSG_ORIG(MSG_QSTR_ATSIGN)); 2114 case TK_DASH: 2115 return (MSG_ORIG(MSG_QSTR_DASH)); 2116 case TK_LEFTBKT: 2117 return (MSG_ORIG(MSG_QSTR_LEFTBKT)); 2118 case TK_RIGHTBKT: 2119 return (MSG_ORIG(MSG_QSTR_RIGHTBKT)); 2120 case TK_PIPE: 2121 return (MSG_ORIG(MSG_QSTR_PIPE)); 2122 case TK_INT: 2123 cnt = tkv->tkv_int.tkvi_cnt; 2124 if (cnt >= sizeof (inv_buf->buf)) 2125 cnt = sizeof (inv_buf->buf) - 1; 2126 (void) memcpy(inv_buf->buf, tkv->tkv_int.tkvi_str, cnt); 2127 inv_buf->buf[cnt] = '\0'; 2128 return (inv_buf->buf); 2129 case TK_STAR: 2130 return (MSG_ORIG(MSG_QSTR_STAR)); 2131 case TK_BANG: 2132 return (MSG_ORIG(MSG_QSTR_BANG)); 2133 default: 2134 assert(0); 2135 break; 2136 } 2137 2138 /*NOTREACHED*/ 2139 return (MSG_INTL(MSG_MAP_INTERR)); 2140 } 2141 2142 /* 2143 * Advance the input to the first non-empty line, and determine 2144 * the mapfile version. The version is specified by the mapfile 2145 * using a $mapfile_version directive. The original System V 2146 * syntax lacks this directive, and we use that fact to identify 2147 * such files. SysV mapfile are implicitly defined to have version 1. 2148 * 2149 * entry: 2150 * ofl - Output file descriptor 2151 * mf - Mapfile block 2152 * 2153 * exit: 2154 * On success, updates mf->mf_version, and returns TRUE (1). 2155 * On failure, returns FALSE (0). 2156 */ 2157 static Boolean 2158 mapfile_version(Mapfile *mf) 2159 { 2160 char *line_start = mf->mf_next; 2161 Boolean cont = TRUE; 2162 Boolean status = TRUE; /* Assume success */ 2163 Token tok; 2164 2165 mf->mf_version = MFV_SYSV; 2166 2167 /* 2168 * Cycle through the characters looking for tokens. Although the 2169 * true version is not known yet, we use the v2 dispatch table. 2170 * It contains control directives, which we need for this search, 2171 * and the other TK_OP_ tokens we will recognize and act on are the 2172 * same for both tables. 2173 * 2174 * It is important not to process any tokens that would lead to 2175 * a non-OP token: 2176 * 2177 * - The version is required to interpret them 2178 * - Our mapfile descriptor is not fully initialized, 2179 * attempts to run that code will crash the program. 2180 */ 2181 while (cont) { 2182 /* Map the character to a dispatch action */ 2183 tok = (*mf->mf_next & 0x80) ? 2184 TK_OP_ILLCHR : gettok_dispatch_v2[*mf->mf_next]; 2185 2186 switch (tok) { 2187 case TK_OP_WS: /* White space */ 2188 mf->mf_next++; 2189 break; 2190 2191 case TK_OP_NL: /* White space too, but bump line number. */ 2192 mf->mf_next++; 2193 mf->mf_lineno++; 2194 break; 2195 2196 case TK_OP_CMT: 2197 advance_to_eol(&mf->mf_next); 2198 break; 2199 2200 case TK_OP_CDIR: 2201 /* 2202 * Control directives are only valid at the start 2203 * of a line. However, as we have not yet seen 2204 * a token, we do not need to test for this, and 2205 * can safely assume that we are at the start. 2206 */ 2207 if (!strncasecmp(mf->mf_next, 2208 MSG_ORIG(MSG_STR_CDIR_MFVER), 2209 MSG_STR_CDIR_MFVER_SIZE) && 2210 isspace_nonl(*(mf->mf_next + 2211 MSG_STR_CDIR_MFVER_SIZE))) { 2212 ld_map_tkval_t ver; 2213 2214 mf->mf_next += MSG_STR_CDIR_MFVER_SIZE + 1; 2215 if (!ld_map_getint(mf, &ver, TRUE)) { 2216 status = cont = FALSE; 2217 break; 2218 } 2219 /* 2220 * Is it a valid version? Note that we 2221 * intentionally do not allow you to 2222 * specify version 1 using the $mapfile_version 2223 * syntax, because that's reserved to version 2224 * 2 and up. 2225 */ 2226 if ((ver.tkv_int.tkvi_value < 2) || 2227 (ver.tkv_int.tkvi_value >= MFV_NUM)) { 2228 const char *fmt; 2229 2230 fmt = (ver.tkv_int.tkvi_value < 2) ? 2231 MSG_INTL(MSG_MAP_CDIR_BADVDIR) : 2232 MSG_INTL(MSG_MAP_CDIR_BADVER); 2233 mf_fatal(mf, fmt, 2234 EC_WORD(ver.tkv_int.tkvi_value)); 2235 status = cont = FALSE; 2236 break; 2237 } 2238 mf->mf_version = ver.tkv_int.tkvi_value; 2239 cont = FALSE; /* Version recovered. All done */ 2240 break; 2241 } 2242 /* 2243 * Not a version directive. Reset the current position 2244 * to the start of the current line and stop here. 2245 * SysV syntax applies. 2246 */ 2247 mf->mf_next = line_start; 2248 cont = FALSE; 2249 break; 2250 2251 default: 2252 /* 2253 * If we see anything else, then stop at this point. 2254 * The file has System V syntax (version 1), and the 2255 * next token should be interpreted as such. 2256 */ 2257 cont = FALSE; 2258 break; 2259 } 2260 } 2261 2262 return (status); 2263 } 2264 2265 /* 2266 * Parse the mapfile. 2267 */ 2268 Boolean 2269 ld_map_parse(const char *mapfile, Ofl_desc *ofl) 2270 { 2271 struct stat stat_buf; /* stat of mapfile */ 2272 int mapfile_fd; /* descriptor for mapfile */ 2273 int err; 2274 Mapfile *mf; /* Mapfile descriptor */ 2275 size_t name_len; /* strlen(mapfile) */ 2276 2277 /* 2278 * Determine if we're dealing with a file or a directory. 2279 */ 2280 if (stat(mapfile, &stat_buf) == -1) { 2281 err = errno; 2282 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_STAT), mapfile, 2283 strerror(err)); 2284 return (FALSE); 2285 } 2286 if (S_ISDIR(stat_buf.st_mode)) { 2287 DIR *dirp; 2288 struct dirent *denp; 2289 2290 /* 2291 * Open the directory and interpret each visible file as a 2292 * mapfile. 2293 */ 2294 if ((dirp = opendir(mapfile)) == NULL) 2295 return (TRUE); 2296 2297 while ((denp = readdir(dirp)) != NULL) { 2298 char path[PATH_MAX]; 2299 2300 /* 2301 * Ignore any hidden filenames. Construct the full 2302 * pathname to the new mapfile. 2303 */ 2304 if (*denp->d_name == '.') 2305 continue; 2306 (void) snprintf(path, PATH_MAX, MSG_ORIG(MSG_STR_PATH), 2307 mapfile, denp->d_name); 2308 if (!ld_map_parse(path, ofl)) 2309 return (FALSE); 2310 } 2311 (void) closedir(dirp); 2312 return (TRUE); 2313 } else if (!S_ISREG(stat_buf.st_mode)) { 2314 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_NOTREG), mapfile); 2315 return (FALSE); 2316 } 2317 2318 /* Open file */ 2319 if ((mapfile_fd = open(mapfile, O_RDONLY)) == -1) { 2320 err = errno; 2321 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), mapfile, 2322 strerror(err)); 2323 return (FALSE); 2324 } 2325 2326 /* 2327 * Allocate enough memory to hold the state block, mapfile name, 2328 * and mapfile text. Text has alignment 1, so it can follow the 2329 * state block without padding. 2330 */ 2331 name_len = strlen(mapfile) + 1; 2332 mf = libld_malloc(sizeof (*mf) + name_len + stat_buf.st_size + 1); 2333 if (mf == NULL) 2334 return (FALSE); 2335 mf->mf_ofl = ofl; 2336 mf->mf_name = (char *)(mf + 1); 2337 (void) strcpy(mf->mf_name, mapfile); 2338 mf->mf_text = mf->mf_name + name_len; 2339 if (read(mapfile_fd, mf->mf_text, stat_buf.st_size) != 2340 stat_buf.st_size) { 2341 err = errno; 2342 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_READ), mapfile, 2343 strerror(err)); 2344 (void) close(mapfile_fd); 2345 return (FALSE); 2346 } 2347 (void) close(mapfile_fd); 2348 mf->mf_text[stat_buf.st_size] = '\0'; 2349 mf->mf_next = mf->mf_text; 2350 mf->mf_lineno = 1; 2351 mf->mf_next_ch = 0; /* No "lookahead" character yet */ 2352 mf->mf_ec_insndx = 0; /* Insert entrace criteria at top */ 2353 2354 /* 2355 * Read just enough from the mapfile to determine the version, 2356 * and then dispatch to the appropriate code for further processing 2357 */ 2358 if (!mapfile_version(mf)) 2359 return (FALSE); 2360 2361 /* 2362 * Start and continuation masks for unquoted identifier at this 2363 * mapfile version level. 2364 */ 2365 mf->mf_tkid_start = TKID_ATTR_START(mf->mf_version); 2366 mf->mf_tkid_cont = TKID_ATTR_CONT(mf->mf_version); 2367 2368 DBG_CALL(Dbg_map_parse(ofl->ofl_lml, mapfile, mf->mf_version)); 2369 2370 switch (mf->mf_version) { 2371 case MFV_SYSV: 2372 /* Guidance: Use newer mapfile syntax */ 2373 if (OFL_GUIDANCE(ofl, FLG_OFG_NO_MF)) 2374 ld_eprintf(ofl, ERR_GUIDANCE, 2375 MSG_INTL(MSG_GUIDE_MAPFILE), mapfile); 2376 2377 mf->mf_tokdisp = gettok_dispatch_v1; 2378 if (!ld_map_parse_v1(mf)) 2379 return (FALSE); 2380 break; 2381 2382 case MFV_SOLARIS: 2383 mf->mf_tokdisp = gettok_dispatch_v2; 2384 STACK_RESET(lms.lms_cdir_stack); 2385 2386 /* 2387 * If the conditional expression identifier tree has not been 2388 * initialized, set it up. This is only done on the first 2389 * mapfile, because the identifier control directives accumulate 2390 * across all the mapfiles. 2391 */ 2392 if ((lms.lms_cexp_id == NULL) && !cexp_ident_init()) 2393 return (FALSE); 2394 2395 /* 2396 * Tell ld_map_gettoken() we will accept a '$' as starting a 2397 * control directive on the first call. Normally, they are 2398 * only allowed after a newline. 2399 */ 2400 lms.lms_cdir_valid = 1; 2401 2402 if (!ld_map_parse_v2(mf)) 2403 return (FALSE); 2404 2405 /* Did we leave any open $if control directives? */ 2406 if (!STACK_IS_EMPTY(lms.lms_cdir_stack)) { 2407 while (!STACK_IS_EMPTY(lms.lms_cdir_stack)) { 2408 cdir_level_t *level = 2409 &STACK_POP(lms.lms_cdir_stack); 2410 2411 mf_fatal(mf, MSG_INTL(MSG_MAP_CDIR_NOEND), 2412 EC_LINENO(level->cdl_if_lineno)); 2413 } 2414 return (FALSE); 2415 } 2416 break; 2417 } 2418 2419 return (TRUE); 2420 } 2421 2422 /* 2423 * Sort the segment list. This is necessary if a mapfile has set explicit 2424 * virtual addresses for segments, or defined a SEGMENT_ORDER directive. 2425 * 2426 * Only PT_LOAD segments can be assigned a virtual address. These segments can 2427 * be one of two types: 2428 * 2429 * - Standard segments for text, data or bss. These segments will have been 2430 * inserted before the default text (first PT_LOAD) segment. 2431 * 2432 * - Empty (reservation) segments. These segment will have been inserted at 2433 * the end of any default PT_LOAD segments. 2434 * 2435 * Any standard segments that are assigned a virtual address will be sorted, 2436 * and as their definitions precede any default PT_LOAD segments, these segments 2437 * will be assigned sections before any defaults. 2438 * 2439 * Any reservation segments are also sorted amoung themselves, as these segments 2440 * must still follow the standard default segments. 2441 */ 2442 static Boolean 2443 sort_seg_list(Ofl_desc *ofl) 2444 { 2445 APlist *sort_segs = NULL, *load_segs = NULL; 2446 Sg_desc *sgp1; 2447 Aliste idx1; 2448 Aliste nsegs; 2449 2450 2451 /* 2452 * We know the number of elements in the sorted list will be 2453 * the same as the original, so use this as the initial allocation 2454 * size for the replacement aplist. 2455 */ 2456 nsegs = aplist_nitems(ofl->ofl_segs); 2457 2458 2459 /* Add the items below SGID_TEXT to the list */ 2460 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) { 2461 if (sgp1->sg_id >= SGID_TEXT) 2462 break; 2463 2464 if (aplist_append(&sort_segs, sgp1, nsegs) == NULL) 2465 return (FALSE); 2466 } 2467 2468 /* 2469 * If there are any SEGMENT_ORDER items, add them, and set their 2470 * FLG_SG_ORDERED flag to identify them in debug output, and to 2471 * prevent them from being added again below. 2472 */ 2473 for (APLIST_TRAVERSE(ofl->ofl_segs_order, idx1, sgp1)) { 2474 if (aplist_append(&sort_segs, sgp1, nsegs) == NULL) 2475 return (FALSE); 2476 sgp1->sg_flags |= FLG_SG_ORDERED; 2477 } 2478 2479 /* 2480 * Add the loadable segments to another list in sorted order. 2481 */ 2482 DBG_CALL(Dbg_map_sort_title(ofl->ofl_lml, TRUE)); 2483 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) { 2484 DBG_CALL(Dbg_map_sort_seg(ofl->ofl_lml, ELFOSABI_SOLARIS, 2485 ld_targ.t_m.m_mach, sgp1)); 2486 2487 /* Only interested in PT_LOAD items not in SEGMENT_ORDER list */ 2488 if ((sgp1->sg_phdr.p_type != PT_LOAD) || 2489 (sgp1->sg_flags & FLG_SG_ORDERED)) 2490 continue; 2491 2492 /* 2493 * If the loadable segment does not contain a vaddr, simply 2494 * append it to the new list. 2495 */ 2496 if ((sgp1->sg_flags & FLG_SG_P_VADDR) == 0) { 2497 if (aplist_append(&load_segs, sgp1, AL_CNT_SEGMENTS) == 2498 NULL) 2499 return (FALSE); 2500 2501 } else { 2502 Aliste idx2; 2503 Sg_desc *sgp2; 2504 int inserted = 0; 2505 2506 /* 2507 * Traverse the segment list we are creating, looking 2508 * for a segment that defines a vaddr. 2509 */ 2510 for (APLIST_TRAVERSE(load_segs, idx2, sgp2)) { 2511 /* 2512 * Any real segments that contain vaddr's need 2513 * to be sorted. Any reservation segments also 2514 * need to be sorted. However, any reservation 2515 * segments should be placed after any real 2516 * segments. 2517 */ 2518 if (((sgp2->sg_flags & 2519 (FLG_SG_P_VADDR | FLG_SG_EMPTY)) == 0) && 2520 (sgp1->sg_flags & FLG_SG_EMPTY)) 2521 continue; 2522 2523 if ((sgp2->sg_flags & FLG_SG_P_VADDR) && 2524 ((sgp2->sg_flags & FLG_SG_EMPTY) == 2525 (sgp1->sg_flags & FLG_SG_EMPTY))) { 2526 if (sgp1->sg_phdr.p_vaddr == 2527 sgp2->sg_phdr.p_vaddr) { 2528 ld_eprintf(ofl, ERR_FATAL, 2529 MSG_INTL(MSG_MAP_SEGSAME), 2530 sgp1->sg_name, 2531 sgp2->sg_name); 2532 return (FALSE); 2533 } 2534 2535 if (sgp1->sg_phdr.p_vaddr > 2536 sgp2->sg_phdr.p_vaddr) 2537 continue; 2538 } 2539 2540 /* 2541 * Insert this segment before the segment on 2542 * the load_segs list. 2543 */ 2544 if (aplist_insert(&load_segs, sgp1, 2545 AL_CNT_SEGMENTS, idx2) == NULL) 2546 return (FALSE); 2547 inserted = 1; 2548 break; 2549 } 2550 2551 /* 2552 * If the segment being inspected has not been inserted 2553 * in the segment list, simply append it to the list. 2554 */ 2555 if ((inserted == 0) && (aplist_append(&load_segs, 2556 sgp1, AL_CNT_SEGMENTS) == NULL)) 2557 return (FALSE); 2558 } 2559 } 2560 2561 /* 2562 * Add the sorted loadable segments to our initial segment list. 2563 */ 2564 for (APLIST_TRAVERSE(load_segs, idx1, sgp1)) { 2565 if (aplist_append(&sort_segs, sgp1, AL_CNT_SEGMENTS) == NULL) 2566 return (FALSE); 2567 } 2568 2569 /* 2570 * Add all other segments to our list. 2571 */ 2572 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) { 2573 if ((sgp1->sg_id < SGID_TEXT) || 2574 (sgp1->sg_phdr.p_type == PT_LOAD) || 2575 (sgp1->sg_flags & FLG_SG_ORDERED)) 2576 continue; 2577 2578 if (aplist_append(&sort_segs, sgp1, AL_CNT_SEGMENTS) == NULL) 2579 return (FALSE); 2580 } 2581 2582 /* 2583 * Free the original list, and the pt_load list, and use 2584 * the new list as the segment list. 2585 */ 2586 free(ofl->ofl_segs); 2587 if (load_segs) free(load_segs); 2588 ofl->ofl_segs = sort_segs; 2589 2590 if (DBG_ENABLED) { 2591 Dbg_map_sort_title(ofl->ofl_lml, FALSE); 2592 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) { 2593 Dbg_map_sort_seg(ofl->ofl_lml, ELFOSABI_SOLARIS, 2594 ld_targ.t_m.m_mach, sgp1); 2595 } 2596 } 2597 2598 return (TRUE); 2599 } 2600 2601 /* 2602 * After all mapfiles have been processed, this routine is used to 2603 * finish any remaining mapfile related work. 2604 * 2605 * exit: 2606 * Returns TRUE on success, and FALSE on failure. 2607 */ 2608 Boolean 2609 ld_map_post_process(Ofl_desc *ofl) 2610 { 2611 Aliste idx, idx2; 2612 Is_desc *isp; 2613 Sg_desc *sgp; 2614 Ent_desc *enp; 2615 Sg_desc *first_seg = NULL; 2616 2617 2618 DBG_CALL(Dbg_map_post_title(ofl->ofl_lml)); 2619 2620 /* 2621 * Per-segment processing: 2622 * - Identify segments with explicit virtual address 2623 * - Details of input and output section order 2624 */ 2625 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp)) { 2626 /* 2627 * We are looking for segments. Program headers that represent 2628 * segments are required to have a non-NULL name pointer, 2629 * while that those that do not are required to have a 2630 * NULL name pointer. 2631 */ 2632 if (sgp->sg_name == NULL) 2633 continue; 2634 2635 /* Remember the first non-disabled segment */ 2636 if ((first_seg == NULL) && !(sgp->sg_flags & FLG_SG_DISABLED)) 2637 first_seg = sgp; 2638 2639 /* 2640 * If a segment has an explicit virtual address, we will 2641 * need to sort the segments. 2642 */ 2643 if (sgp->sg_flags & FLG_SG_P_VADDR) 2644 ofl->ofl_flags1 |= FLG_OF1_VADDR; 2645 2646 /* 2647 * The FLG_OF_OS_ORDER flag enables the code that does 2648 * output section ordering. Set if the segment has 2649 * a non-empty output section order list. 2650 */ 2651 if (alist_nitems(sgp->sg_os_order) > 0) 2652 ofl->ofl_flags |= FLG_OF_OS_ORDER; 2653 2654 /* 2655 * The version 1 and version 2 syntaxes for input section 2656 * ordering are different and incompatible enough that we 2657 * only allow the use of one or the other for a given segment: 2658 * 2659 * v1) The version 1 syntax has the user set the ?O flag on 2660 * the segment. If this is done, all input sections placed 2661 * via an entrance criteria that has a section name are to 2662 * be sorted, using the order of the entrance criteria 2663 * as the sort key. 2664 * 2665 * v2) The version 2 syntax has the user specify a name for 2666 * the entry criteria, and then provide a list of entry 2667 * criteria names via the IS_ORDER segment attribute. 2668 * Sections placed via the criteria listed in IS_ORDER 2669 * are sorted, and the others are not. 2670 * 2671 * Regardless of the syntax version used, the section sorting 2672 * code expects the following: 2673 * 2674 * - Segments requiring input section sorting have the 2675 * FLG_SG_IS_ORDER flag set 2676 * 2677 * - Entrance criteria referencing the segment that 2678 * participate in input section sorting have a non-zero 2679 * sort key in their ec_ordndx field. 2680 * 2681 * At this point, the following are true: 2682 * 2683 * - All entrance criteria have ec_ordndx set to 0. 2684 * - Segments that require the version 1 behavior have 2685 * the FLG_SG_IS_ORDER flag set, and the segments 2686 * sg_is_order list is empty. 2687 * - Segments that require the version 2 behavior do not 2688 * have FLG_SG_IS_ORDER set, and the sg_is_order list is 2689 * non-empty. This list contains the names of the entrance 2690 * criteria that will participate in input section sorting, 2691 * and their relative order in the list provides the 2692 * sort key to use. 2693 * 2694 * We must detect these two cases, set the FLG_SG_IS_ORDER 2695 * flag as necessary, and fill in all entrance criteria 2696 * sort keys. If any input section sorting is to be done, 2697 * we also set the FLG_OF_IS_ORDER flag on the output descriptor 2698 * to enable the code that does that work. 2699 */ 2700 2701 /* Version 1: ?O flag? */ 2702 if (sgp->sg_flags & FLG_SG_IS_ORDER) { 2703 Word index = 0; 2704 2705 ofl->ofl_flags |= FLG_OF_IS_ORDER; 2706 DBG_CALL(Dbg_map_ent_ord_title(ofl->ofl_lml, 2707 sgp->sg_name)); 2708 2709 /* 2710 * Give each user defined entrance criteria for this 2711 * segment that specifies a section name a 2712 * monotonically increasing sort key. 2713 */ 2714 for (APLIST_TRAVERSE(ofl->ofl_ents, idx2, enp)) 2715 if ((enp->ec_segment == sgp) && 2716 (enp->ec_is_name != NULL) && 2717 ((enp->ec_flags & FLG_EC_BUILTIN) == 0)) 2718 enp->ec_ordndx = ++index; 2719 continue; 2720 } 2721 2722 /* Version 2: SEGMENT IS_ORDER list? */ 2723 if (aplist_nitems(sgp->sg_is_order) > 0) { 2724 Word index = 0; 2725 2726 ofl->ofl_flags |= FLG_OF_IS_ORDER; 2727 DBG_CALL(Dbg_map_ent_ord_title(ofl->ofl_lml, 2728 sgp->sg_name)); 2729 2730 /* 2731 * Give each entrance criteria in the sg_is_order 2732 * list a monotonically increasing sort key. 2733 */ 2734 for (APLIST_TRAVERSE(sgp->sg_is_order, idx2, enp)) { 2735 enp->ec_ordndx = ++index; 2736 enp->ec_segment->sg_flags |= FLG_SG_IS_ORDER; 2737 } 2738 } 2739 } 2740 2741 /* Sort the segment descriptors if necessary */ 2742 if (((ofl->ofl_flags1 & FLG_OF1_VADDR) || 2743 (aplist_nitems(ofl->ofl_segs_order) > 0)) && 2744 !sort_seg_list(ofl)) 2745 return (FALSE); 2746 2747 /* 2748 * If the output file is a static file without an interpreter, and 2749 * if any virtual address is specified, then set the NOHDR flag for 2750 * backward compatibility. 2751 */ 2752 if (!(ofl->ofl_flags & (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) && 2753 !(ofl->ofl_osinterp) && (ofl->ofl_flags1 & FLG_OF1_VADDR)) 2754 ofl->ofl_dtflags_1 |= DF_1_NOHDR; 2755 2756 if (ofl->ofl_flags & FLG_OF_RELOBJ) { 2757 /* 2758 * NOHDR has no effect on a relocatable file. 2759 * Make sure this flag isn't set. 2760 */ 2761 ofl->ofl_dtflags_1 &= ~DF_1_NOHDR; 2762 } else if (first_seg != NULL) { 2763 /* 2764 * DF_1_NOHDR might have been set globally by the HDR_NOALLOC 2765 * directive. If not, then we want to check the per-segment 2766 * flag for the first loadable segment and propagate it 2767 * if set. 2768 */ 2769 if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0) { 2770 /* 2771 * If we sorted the segments, the first segment 2772 * may have changed. 2773 */ 2774 if ((ofl->ofl_flags1 & FLG_OF1_VADDR) || 2775 (aplist_nitems(ofl->ofl_segs_order) > 0)) { 2776 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp)) { 2777 if (sgp->sg_name == NULL) 2778 continue; 2779 if ((sgp->sg_flags & FLG_SG_DISABLED) == 2780 0) { 2781 first_seg = sgp; 2782 break; 2783 } 2784 } 2785 } 2786 2787 /* 2788 * If the per-segment NOHDR flag is set on our first 2789 * segment, then make it take effect. 2790 */ 2791 if (first_seg->sg_flags & FLG_SG_NOHDR) 2792 ofl->ofl_dtflags_1 |= DF_1_NOHDR; 2793 } 2794 2795 /* 2796 * For executable and shared objects, the first segment must 2797 * be loadable unless NOHDR was specified, because the ELF 2798 * header must simultaneously lie at offset 0 of the file and 2799 * be included in the first loadable segment. This isn't 2800 * possible if some other segment type starts the file 2801 */ 2802 if (!(ofl->ofl_dtflags_1 & DF_1_NOHDR) && 2803 (first_seg->sg_phdr.p_type != PT_LOAD)) { 2804 Conv_inv_buf_t inv_buf; 2805 2806 ld_eprintf(ofl, ERR_FATAL, 2807 MSG_INTL(MSG_SEG_FIRNOTLOAD), 2808 conv_phdr_type(ELFOSABI_SOLARIS, ld_targ.t_m.m_mach, 2809 first_seg->sg_phdr.p_type, 0, &inv_buf), 2810 first_seg->sg_name); 2811 return (FALSE); 2812 } 2813 } 2814 2815 /* 2816 * Mapfiles may have been used to create symbol definitions 2817 * with backing storage. Although the backing storage is 2818 * associated with an input section, the association of the 2819 * section to an output section (and segment) is initially 2820 * deferred. Now that all mapfile processing is complete, any 2821 * entrance criteria requirements have been processed, and 2822 * these backing storage sections can be associated with the 2823 * appropriate output section (and segment). 2824 */ 2825 if (ofl->ofl_maptext || ofl->ofl_mapdata) 2826 DBG_CALL(Dbg_sec_backing(ofl->ofl_lml)); 2827 2828 for (APLIST_TRAVERSE(ofl->ofl_maptext, idx, isp)) { 2829 if (ld_place_section(ofl, isp, NULL, 2830 ld_targ.t_id.id_text, NULL) == (Os_desc *)S_ERROR) 2831 return (FALSE); 2832 } 2833 2834 for (APLIST_TRAVERSE(ofl->ofl_mapdata, idx, isp)) { 2835 if (ld_place_section(ofl, isp, NULL, 2836 ld_targ.t_id.id_data, NULL) == (Os_desc *)S_ERROR) 2837 return (FALSE); 2838 } 2839 2840 return (TRUE); 2841 }