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.
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.
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]
23 * Copyright (c) 1988 AT&T
26 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
30 * Map file parsing (Shared Core Code).
46 * There are two styles of mapfile supported by the link-editor:
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
52 * 2) A newer syntax, currently at version 2.
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:
58 * 1) Too cryptic: It's hard for people to remember which character
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.
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.
70 * The new syntax uses the following terminology:
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.
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
81 * - Regular Directives are names (SYMBOL, VERSION, etc) that convey
82 * directions to the link-editor for building the output object.
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.
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.
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 */
103 /* Operators in the expressions accepted by $if/$elif */
105 CEXP_OP_NONE
, /* Not an operator */
106 CEXP_OP_AND
, /* && */
109 CEXP_OP_OPAR
, /* ( */
114 * Type of conditional expression identifier AVL tree nodes
116 typedef struct cexp_name_node
{
117 avl_node_t ceid_avlnode
; /* AVL book-keeping */
118 const char *ceid_name
; /* boolean identifier name */
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.
127 #define STACK(_type) \
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 */ \
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().
140 typedef STACK(void) generic_stack_t
;
143 * Ensure that the stack has enough room to push one more item
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)))
151 * Reset a stack to empty.
153 #define STACK_RESET(_stack) (_stack).stk_n = 0;
156 * True if stack is empty, False otherwise.
158 #define STACK_IS_EMPTY(_stack) ((_stack).stk_n == 0)
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:
165 * STACK_PUSH(stack) = value;
167 #define STACK_PUSH(_stack) (_stack).stk_s[(_stack).stk_n++]
170 * Pop a value off a stack. Caller must ensure
171 * that stack is not empty.
173 #define STACK_POP(_stack) ((_stack).stk_s[--(_stack).stk_n])
176 * Access top element on stack without popping. Caller must ensure
177 * that stack is not empty.
179 #define STACK_TOP(_stack) (((_stack).stk_s)[(_stack).stk_n - 1])
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.
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.
192 #define CDIR_STACK_INIT 1
193 #define CEXP_OP_STACK_INIT 1
194 #define CEXP_VAL_STACK_INIT 1
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 */
203 * Persistent state maintained by map module in between calls.
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:
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.
214 * Until then, it is simpler not to expose these details.
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
;
223 static ld_map_state_t lms
;
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
231 * This table must be kept in sync with tkid_attr[] below.
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.
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 */
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.
378 * This table must be kept in sync with tkid_attr[] below.
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.
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 */
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.
524 static const char tkid_attr
[128] = {
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 */
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 */
558 TKID_ATTR(1), /* 33 - ! */
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 */
585 TKID_ATTR(1), /* 60 - < */
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 */
657 * Advance the given string pointer to the next newline character,
658 * or the terminating NULL if there is none.
661 advance_to_eol(char **str
)
665 while ((*s
!= '\n') && (*s
!= '\0'))
671 * Insert a NULL patch at the given address
674 null_patch_set(char *str
, ld_map_npatch_t
*np
)
685 null_patch_undo(ld_map_npatch_t
*np
)
687 *np
->np_ptr
= np
->np_ch
;
691 * Insert a NULL patch at the end of the line containing str.
694 null_patch_eol(char *str
, ld_map_npatch_t
*np
)
696 advance_to_eol(&str
);
697 null_patch_set(str
, np
);
701 * Locate the end of an unquoted identifier.
704 * mf - Mapfile descriptor, positioned to first character
708 * If the item pointed at by mf is not an identifier, returns NULL.
709 * Otherwise, returns pointer to character after the last character
713 ident_delimit(Mapfile
*mf
)
715 char *str
= mf
->mf_next
;
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
);
727 /* Keep going until we hit a non-continuing character */
728 for (c
= *str
; !(c
& 0x80) && (tkid_attr
[c
] & mf
->mf_tkid_cont
);
736 * Allocate memory for a stack.
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.
745 * Returns (1) on success. On error (memory allocation), a message
746 * is printed and False (0) is returned.
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.
757 stack_resize(generic_stack_t
*stack
, size_t n_default
, size_t elt_size
)
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);
766 newaddr
= libld_realloc(stack
->stk_s
, new_n_alloc
* elt_size
);
770 stack
->stk_s
= newaddr
;
771 stack
->stk_n_alloc
= new_n_alloc
;
776 * AVL comparison function for cexp_id_node_t items.
779 * n1, n2 - pointers to nodes to be compared
782 * Returns -1 if (n1 < n2), 0 if they are equal, and 1 if (n1 > n2)
785 cexp_ident_cmp(const void *n1
, const void *n2
)
789 rc
= strcmp(((cexp_id_node_t
*)n1
)->ceid_name
,
790 ((cexp_id_node_t
*)n2
)->ceid_name
);
801 * Returns True (1) if name is in the conditional expression identifier
802 * AVL tree, and False (0) otherwise.
805 cexp_ident_test(const char *name
)
809 node
.ceid_name
= name
;
810 return (avl_find(lms
.lms_cexp_id
, &node
, 0) != NULL
);
814 * Add a new boolean identifier to the conditional expression identifier
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.
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.
829 cexp_ident_add(Mapfile
*mf
, const char *name
)
831 cexp_id_node_t
*node
;
834 DBG_CALL(Dbg_map_cexp_id(mf
->mf_ofl
->ofl_lml
, 1,
835 mf
->mf_name
, mf
->mf_lineno
, name
));
837 /* If is already known, don't do it again */
838 if (cexp_ident_test(name
))
842 if ((node
= libld_calloc(sizeof (*node
), 1)) == NULL
)
844 node
->ceid_name
= name
;
845 avl_add(lms
.lms_cexp_id
, node
);
850 * Remove a boolean identifier from the conditional expression identifier
854 * mf - Mapfile descriptor
855 * name - Name of identifier.
858 * If the name was in the tree, it has been removed. If not,
859 * then this routine quietly returns.
862 cexp_ident_clear(Mapfile
*mf
, const char *name
)
865 cexp_id_node_t
*real_node
;
867 DBG_CALL(Dbg_map_cexp_id(mf
->mf_ofl
->ofl_lml
, 0,
868 mf
->mf_name
, mf
->mf_lineno
, name
));
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
);
877 * Initialize the AVL tree that holds the names of the currently defined
878 * boolean identifiers for conditional expressions ($if/$elif).
881 * ofl - Output file descriptor
884 * On success, TRUE (1) is returned and lms.lms_cexp_id is ready for use.
885 * On failure, FALSE (0) is returned.
888 cexp_ident_init(void)
890 /* If already done, use it */
891 if (lms
.lms_cexp_id
!= NULL
)
894 lms
.lms_cexp_id
= libld_calloc(sizeof (*lms
.lms_cexp_id
), 1);
895 if (lms
.lms_cexp_id
== NULL
)
897 avl_create(lms
.lms_cexp_id
, cexp_ident_cmp
, sizeof (cexp_id_node_t
),
898 SGSOFFSETOF(cexp_id_node_t
, ceid_avlnode
));
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)
907 switch (ld_targ
.t_m
.m_mach
) {
910 if (cexp_ident_add(NULL
, MSG_ORIG(MSG_STR_UX86
)) == 0)
916 if (cexp_ident_add(NULL
, MSG_ORIG(MSG_STR_USPARC
)) == 0)
921 /* true is always defined */
922 if (cexp_ident_add(NULL
, MSG_ORIG(MSG_STR_TRUE
)) == 0)
929 * Validate the string starting at mf->mf_next as being a
930 * boolean conditional expression identifier.
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).
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
947 * On failure, returns FALSE (0).
950 cexp_ident_validate(Mapfile
*mf
, size_t *len
, const char *directive
)
954 if ((tail
= ident_delimit(mf
)) == NULL
)
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.
964 *len
= tail
- mf
->mf_next
;
965 } else if (*tail
!= '\0') {
967 while (isspace(*tail
))
970 mf_fatal(mf
, MSG_INTL(MSG_MAP_BADEXTRA
), directive
);
979 * Push a new operator onto the conditional expression operator stack.
982 * mf - Mapfile descriptor
983 * op - Operator to push
986 * On success, TRUE (1) is returned, otherwise FALSE (0).
989 cexp_push_op(cexp_op_t op
)
991 if (STACK_RESERVE(lms
.lms_cexp_op_stack
, CEXP_OP_STACK_INIT
) == 0)
994 STACK_PUSH(lms
.lms_cexp_op_stack
) = op
;
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.
1003 * On success, returns TRUE (1). On error, FALSE (0) is returned,
1004 * and the caller is responsible for issuing the error.
1012 op
= STACK_POP(lms
.lms_cexp_op_stack
);
1015 if (lms
.lms_cexp_val_stack
.stk_n
< 2)
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
);
1023 if (lms
.lms_cexp_val_stack
.stk_n
< 2)
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
);
1031 if (lms
.lms_cexp_val_stack
.stk_n
< 1)
1033 STACK_TOP(lms
.lms_cexp_val_stack
) =
1034 !STACK_TOP(lms
.lms_cexp_val_stack
);
1044 * Evaluate an expression for a $if/$elif control directive.
1047 * mf - Mapfile descriptor for NULL terminated string
1048 * containing the expression.
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.
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.
1062 * The expressions consist of boolean identifiers, which can be
1063 * combined using the following operators, listed from highest
1064 * precedence to least:
1067 * -------------------------------------------------
1068 * (expr) sub-expression, non-associative
1069 * ! logical negation, prefix, left associative
1070 * && || logical and/or, binary, left associative
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.
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.
1085 cexp_eval_expr(Mapfile
*mf
)
1089 cexp_op_t new_op
= CEXP_OP_AND
; /* to catch binop at start */
1091 char *str
= mf
->mf_next
;
1093 STACK_RESET(lms
.lms_cexp_op_stack
);
1094 STACK_RESET(lms
.lms_cexp_val_stack
);
1096 for (; *str
; str
++) {
1098 /* Skip whitespace */
1099 while (isspace(*str
))
1107 if (*(str
+ 1) != *str
)
1109 if ((new_op
!= CEXP_OP_NONE
) &&
1110 (new_op
!= CEXP_OP_CPAR
)) {
1111 mf_fatal0(mf
, MSG_INTL(MSG_MAP_CEXP_BADOPUSE
));
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.
1121 while (!STACK_IS_EMPTY(lms
.lms_cexp_op_stack
)) {
1122 cexp_op_t op
= STACK_TOP(lms
.lms_cexp_op_stack
);
1125 if ((op
!= CEXP_OP_AND
) && (op
!= CEXP_OP_OR
) &&
1126 (op
!= CEXP_OP_NEG
))
1129 if (!cexp_eval_op())
1130 goto semantic_error
;
1133 new_op
= (*str
== '&') ? CEXP_OP_AND
: CEXP_OP_OR
;
1134 if (!cexp_push_op(new_op
))
1139 new_op
= CEXP_OP_NEG
;
1140 if (!cexp_push_op(new_op
))
1145 new_op
= CEXP_OP_OPAR
;
1146 if (!cexp_push_op(new_op
))
1151 new_op
= CEXP_OP_CPAR
;
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
;
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.
1164 if (STACK_IS_EMPTY(lms
.lms_cexp_op_stack
))
1165 goto unbalpar_error
;
1166 lms
.lms_cexp_op_stack
.stk_n
--; /* Pop OPAR */
1170 /* Ensure there's room to push another operand */
1171 if (STACK_RESERVE(lms
.lms_cexp_val_stack
,
1172 CEXP_VAL_STACK_INIT
) == 0)
1174 new_op
= CEXP_OP_NONE
;
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
1183 if ((*str
== '0') || (*str
== '1')) {
1184 STACK_PUSH(lms
.lms_cexp_val_stack
) =
1189 /* Look up the identifier */
1190 ident
= mf
->mf_next
= str
;
1191 if (!cexp_ident_validate(mf
, &len
, NULL
))
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
);
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
;
1208 if (!cexp_eval_op())
1209 goto semantic_error
;
1212 /* There should be exactly one value left */
1213 if (lms
.lms_cexp_val_stack
.stk_n
!= 1)
1214 goto semantic_error
;
1216 /* Final value is the result */
1217 return (lms
.lms_cexp_val_stack
.stk_s
[0]);
1219 /* Errors issued more than once are handled below, accessed via goto */
1221 token_error
: /* unexpected characters in input stream */
1222 mf_fatal(mf
, MSG_INTL(MSG_MAP_CEXP_TOKERR
), str
);
1225 semantic_error
: /* valid tokens, but in invalid arrangement */
1226 mf_fatal0(mf
, MSG_INTL(MSG_MAP_CEXP_SEMERR
));
1229 unbalpar_error
: /* Extra or missing parenthesis */
1230 mf_fatal0(mf
, MSG_INTL(MSG_MAP_CEXP_UNBALPAR
));
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.
1240 * mf - Mapfile descriptor
1243 * Returns TRUE (1) for success, and FALSE (0) on error. In the
1244 * error case, a descriptive error is issued.
1247 cdir_process(Mapfile
*mf
)
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 */
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 */
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 */
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
},
1296 ARG_T_IGN
, CDIR_T_UNKNOWN
}
1299 cdir_match_t
*mdptr
;
1301 int expr_eval
; /* Result of evaluating ARG_T_EXPR */
1303 cdir_level_t
*level
;
1304 int pass
, parent_pass
; /* Currently accepting input */
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
;
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
;
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)
1321 tail
= mf
->mf_next
+ mdptr
->md_size
;
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.
1328 if (!isspace(*tail
) && (*tail
!= '\0'))
1331 /* We have matched a valid control directive */
1335 /* Advance input to end of the current line */
1336 advance_to_eol(&mf
->mf_next
);
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.
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.
1349 if (mdptr
->md_name
== NULL
)
1350 arg_mf
.mf_text
= arg_mf
.mf_next
;
1352 arg_mf
.mf_text
= arg_mf
.mf_next
= tail
;
1355 * Null terminate the arguments, and advance the main mapfile
1356 * state block to the next line.
1358 if (*mf
->mf_next
== '\n') {
1359 *mf
->mf_next
++ = '\0';
1363 /* Skip leading whitespace to arguments */
1364 while (isspace(*arg_mf
.mf_next
))
1367 /* Strip off any comment present on the line */
1368 for (tail
= arg_mf
.mf_next
; *tail
; tail
++)
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.
1382 if (pass
|| (parent_pass
&& (mdptr
->md_op
== CDIR_T_ELIF
))) {
1383 switch (mdptr
->md_arg
) {
1385 if (*arg_mf
.mf_next
== '\0')
1387 /* Args are present, but not wanted */
1388 mf_fatal(&arg_mf
, MSG_INTL(MSG_MAP_CDIR_REQNOARG
),
1393 /* Ensure that arguments are present */
1394 if (*arg_mf
.mf_next
== '\0')
1396 expr_eval
= cexp_eval_expr(&arg_mf
);
1397 if (expr_eval
== -1)
1402 /* Ensure that arguments are present */
1403 if (*arg_mf
.mf_next
== '\0')
1405 if (!cexp_ident_validate(&arg_mf
, NULL
,
1411 /* Ensure that arguments are present */
1412 if (*arg_mf
.mf_next
== '\0')
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)))
1425 * Carry out the specified control directive:
1427 if (!STACK_IS_EMPTY(lms
.lms_cdir_stack
))
1428 level
= &STACK_TOP(lms
.lms_cdir_stack
);
1430 switch (mdptr
->md_op
) {
1431 case CDIR_T_UNKNOWN
: /* Unrecognized control directive */
1434 mf_fatal0(&arg_mf
, MSG_INTL(MSG_MAP_CDIR_BAD
));
1438 if (pass
&& !cexp_ident_add(&arg_mf
, arg_mf
.mf_next
))
1444 cexp_ident_clear(&arg_mf
, arg_mf
.mf_next
);
1450 mf_fatal(&arg_mf
, MSG_INTL(MSG_MAP_CDIR_ERROR
),
1454 case CDIR_T_VERSION
:
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.
1463 mf_fatal0(&arg_mf
, MSG_INTL(MSG_MAP_CDIR_REPVER
));
1467 /* Push a new level on the conditional input stack */
1468 if (STACK_RESERVE(lms
.lms_cdir_stack
, CDIR_STACK_INIT
) == 0)
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;
1475 * If previous level is not passing, this level is disabled.
1476 * Otherwise, the expression value determines what happens.
1479 level
->cdl_done
= level
->cdl_pass
= expr_eval
;
1481 level
->cdl_done
= 1;
1482 level
->cdl_pass
= 0;
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
));
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
));
1503 * Accept text from $elif if the level isn't already
1504 * done and the expression evaluates to true.
1506 level
->cdl_pass
= !level
->cdl_done
&& expr_eval
;
1507 if (level
->cdl_pass
)
1508 level
->cdl_done
= 1;
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
));
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
));
1526 level
->cdl_else_lineno
= arg_mf
.mf_lineno
;
1528 /* Accept text from $else if the level isn't already done */
1529 level
->cdl_pass
= !level
->cdl_done
;
1530 level
->cdl_done
= 1;
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
));
1540 if (--lms
.lms_cdir_stack
.stk_n
> 0)
1541 level
= &STACK_TOP(lms
.lms_cdir_stack
);
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
) {
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
));
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.
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:
1572 * EOF: Return and let ld_map_gettoken() report it
1573 * Control Directive: Restart this function / evaluate new directive
1575 while (*mf
->mf_next
!= '\0') {
1576 /* Skip leading whitespace */
1577 while (isspace_nonl(*mf
->mf_next
))
1581 * Control directives start with a '$'. If we hit
1582 * one, restart the function at this point
1584 if (*mf
->mf_next
== '$')
1587 /* Not a control directive, so advance input to next line */
1588 advance_to_eol(&mf
->mf_next
);
1589 if (*mf
->mf_next
== '\n') {
1595 assert(*mf
->mf_next
== '\0');
1599 * Control directives that require an argument that is not present
1600 * jump here to report the error and exit.
1603 mf_fatal(&arg_mf
, MSG_INTL(MSG_MAP_CDIR_REQARG
), mdptr
->md_name
);
1610 * Convert a string to lowercase.
1613 ld_map_lowercase(char *str
)
1615 while (*str
= tolower(*str
))
1621 * Wrappper on strtoul()/strtoull(), adapted to return an Xword.
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.
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
1638 ld_map_strtoxword(const char *restrict str
, char **restrict endptr
,
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 */
1647 #define FUNC strtoul
1648 #define FUNC_MAX ULONG_MAX
1649 #define XWORD_MAX UINT_MAX
1653 char *endptr_local
; /* Used if endptr is NULL */
1656 endptr
= &endptr_local
;
1659 value
= FUNC(str
, endptr
, 0);
1660 if ((errno
!= 0) || (str
== *endptr
)) {
1661 if (value
== FUNC_MAX
)
1662 return (STRTOXWORD_TOOBIG
);
1664 return (STRTOXWORD_BAD
);
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.
1673 #if FUNC_MAX != XWORD_MAX
1674 if (value
> XWORD_MAX
)
1675 return (STRTOXWORD_TOOBIG
);
1679 return (STRTOXWORD_OK
);
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.
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.
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).
1707 ld_map_getint(Mapfile
*mf
, ld_map_tkval_t
*value
, Boolean notail
)
1709 ld_map_strtoxword_t s2xw_ret
;
1712 char *errstr
= mf
->mf_next
;
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
);
1722 mf_fatal(mf
, MSG_INTL(MSG_MAP_MALVALUE
), errstr
);
1723 null_patch_undo(&np
);
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
))
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
);
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().
1750 * mf - Mapfile descriptor, positioned to the first character of
1752 * flags - Bitmask of options to control ld_map_gettoken()s behavior
1753 * tkv- Address of pointer to variable to receive token value.
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.
1760 gettoken_ident(Mapfile
*mf
, int flags
, ld_map_tkval_t
*tkv
)
1766 tkv
->tkv_str
= mf
->mf_next
;
1767 if ((end
= ident_delimit(mf
)) == NULL
)
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:
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
1788 tok
= (*mf
->mf_next
& 0x80) ?
1789 TK_OP_ILLCHR
: mf
->mf_tokdisp
[*mf
->mf_next
];
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
);
1797 case TK_OP_SIMQUOTE
:
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
);
1808 /* Null terminate, saving the replaced character */
1809 mf
->mf_next_ch
= *mf
->mf_next
;
1810 *mf
->mf_next
= '\0';
1812 if (flags
& TK_F_STRLC
)
1813 ld_map_lowercase(tkv
->tkv_str
);
1818 * Convert a quoted string into a TK_STRING token, using simple
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().
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.
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.
1834 gettoken_simquote_str(Mapfile
*mf
, int flags
, ld_map_tkval_t
*tkv
)
1839 str
= mf
->mf_next
++;
1842 while ((*end
!= '\0') && (*end
!= '\n') && (*end
!= quote
))
1844 if (*end
!= quote
) {
1847 null_patch_eol(end
, &np
);
1848 mf_fatal(mf
, MSG_INTL(MSG_MAP_NOTERM
), str
);
1849 null_patch_undo(&np
);
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.
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
);
1866 * Convert a quoted string into a TK_STRING token, using C string literal
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().
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.
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.
1882 gettoken_cquote_str(Mapfile
*mf
, int flags
, ld_map_tkval_t
*tkv
)
1884 char *str
, *cur
, *end
;
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.
1895 str
= mf
->mf_next
++;
1897 cur
= end
= mf
->mf_next
;
1898 for (c
= *end
++; (c
!= '\0') && (c
!= '\n') && (c
!= quote
);
1901 c
= conv_translate_c_esc(&end
);
1903 mf_fatal(mf
, MSG_INTL(MSG_MAP_BADCESC
), *end
);
1909 *cur
= '\0'; /* terminate the result */
1913 null_patch_eol(end
, &np
);
1914 mf_fatal(mf
, MSG_INTL(MSG_MAP_NOTERM
), str
);
1915 null_patch_undo(&np
);
1919 /* end is pointing one character past the closing quote */
1921 tkv
->tkv_str
= str
+ 1; /* Skip opening quote */
1922 if (flags
& TK_F_STRLC
)
1923 ld_map_lowercase(tkv
->tkv_str
);
1928 * Get a token from the mapfile.
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.
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.
1941 ld_map_gettoken(Mapfile
*mf
, int flags
, ld_map_tkval_t
*tkv
)
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.
1954 cdir_allow
= lms
.lms_cdir_valid
;
1955 lms
.lms_cdir_valid
= 0;
1957 /* Cycle through the characters looking for tokens. */
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.
1965 * gettoken_ident() ensures that this is never done to
1966 * a character that starts a string.
1968 if (mf
->mf_next_ch
== 0) {
1971 ch
= mf
->mf_next_ch
;
1972 mf
->mf_next_ch
= 0; /* Reset */
1975 /* Map the character to a dispatch action */
1976 tok
= (ch
& 0x80) ? TK_OP_ILLCHR
: mf
->mf_tokdisp
[ch
];
1979 * Items that require processing are identified as OP tokens.
1980 * We process them, and return a result non-OP token.
1982 * Non-OP tokens are single character tokens, and we return
1987 /* If EOFOK is set, quietly report it as TK_EOF */
1988 if ((flags
& TK_F_EOFOK
) != 0)
1991 /* Treat it as a standard error */
1992 mf_fatal0(mf
, MSG_INTL(MSG_MAP_PREMEOF
));
1996 mf_fatal(mf
, MSG_INTL(MSG_MAP_ILLCHAR
), ch
);
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
);
2008 case TK_OP_WS
: /* White space */
2012 case TK_OP_NL
: /* White space too, but bump line number. */
2018 case TK_OP_SIMQUOTE
:
2019 if (flags
& TK_F_KEYWORD
)
2020 goto tk_op_badkwquote
;
2021 return (gettoken_simquote_str(mf
, flags
, tkv
));
2024 if (flags
& TK_F_KEYWORD
) {
2026 null_patch_eol(mf
->mf_next
, &np
);
2027 mf_fatal(mf
, MSG_INTL(MSG_MAP_BADKWQUOTE
),
2029 null_patch_undo(&np
);
2033 return (gettoken_cquote_str(mf
, flags
, tkv
));
2036 advance_to_eol(&mf
->mf_next
);
2041 * Control directives are only valid at the start
2045 null_patch_eol(mf
->mf_next
, &np
);
2046 mf_fatal(mf
, MSG_INTL(MSG_MAP_CDIR_NOTBOL
),
2048 null_patch_undo(&np
);
2052 if (!cdir_process(mf
))
2056 case TK_OP_NUM
: /* Decimal, hex(0x...), or octal (0...) value */
2057 if (!ld_map_getint(mf
, tkv
, FALSE
))
2061 case TK_OP_ID
: /* Unquoted identifier */
2062 return (gettoken_ident(mf
, flags
, tkv
));
2064 case TK_OP_CEQUAL
: /* += or -= */
2065 if (*(mf
->mf_next
+ 1) != '=')
2067 tok
= (ch
== '+') ? TK_PLUSEQ
: TK_MINUSEQ
;
2071 default: /* Non-OP token */
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.
2087 * tok - Token code. Must not be an OP-token
2091 ld_map_tokenstr(Token tok
, ld_map_tkval_t
*tkv
, Conv_inv_buf_t
*inv_buf
)
2097 return (MSG_ORIG(MSG_STR_ERROR
));
2099 return (MSG_ORIG(MSG_STR_EOF
));
2101 return (tkv
->tkv_str
);
2103 return (MSG_ORIG(MSG_QSTR_COLON
));
2105 return (MSG_ORIG(MSG_QSTR_SEMICOLON
));
2107 return (MSG_ORIG(MSG_QSTR_EQUAL
));
2109 return (MSG_ORIG(MSG_QSTR_PLUSEQ
));
2111 return (MSG_ORIG(MSG_QSTR_MINUSEQ
));
2113 return (MSG_ORIG(MSG_QSTR_ATSIGN
));
2115 return (MSG_ORIG(MSG_QSTR_DASH
));
2117 return (MSG_ORIG(MSG_QSTR_LEFTBKT
));
2119 return (MSG_ORIG(MSG_QSTR_RIGHTBKT
));
2121 return (MSG_ORIG(MSG_QSTR_PIPE
));
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
);
2130 return (MSG_ORIG(MSG_QSTR_STAR
));
2132 return (MSG_ORIG(MSG_QSTR_BANG
));
2139 return (MSG_INTL(MSG_MAP_INTERR
));
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.
2150 * ofl - Output file descriptor
2151 * mf - Mapfile block
2154 * On success, updates mf->mf_version, and returns TRUE (1).
2155 * On failure, returns FALSE (0).
2158 mapfile_version(Mapfile
*mf
)
2160 char *line_start
= mf
->mf_next
;
2161 Boolean cont
= TRUE
;
2162 Boolean status
= TRUE
; /* Assume success */
2165 mf
->mf_version
= MFV_SYSV
;
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.
2174 * It is important not to process any tokens that would lead to
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.
2182 /* Map the character to a dispatch action */
2183 tok
= (*mf
->mf_next
& 0x80) ?
2184 TK_OP_ILLCHR
: gettok_dispatch_v2
[*mf
->mf_next
];
2187 case TK_OP_WS
: /* White space */
2191 case TK_OP_NL
: /* White space too, but bump line number. */
2197 advance_to_eol(&mf
->mf_next
);
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.
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
))) {
2214 mf
->mf_next
+= MSG_STR_CDIR_MFVER_SIZE
+ 1;
2215 if (!ld_map_getint(mf
, &ver
, TRUE
)) {
2216 status
= cont
= FALSE
;
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
2226 if ((ver
.tkv_int
.tkvi_value
< 2) ||
2227 (ver
.tkv_int
.tkvi_value
>= MFV_NUM
)) {
2230 fmt
= (ver
.tkv_int
.tkvi_value
< 2) ?
2231 MSG_INTL(MSG_MAP_CDIR_BADVDIR
) :
2232 MSG_INTL(MSG_MAP_CDIR_BADVER
);
2234 EC_WORD(ver
.tkv_int
.tkvi_value
));
2235 status
= cont
= FALSE
;
2238 mf
->mf_version
= ver
.tkv_int
.tkvi_value
;
2239 cont
= FALSE
; /* Version recovered. All done */
2243 * Not a version directive. Reset the current position
2244 * to the start of the current line and stop here.
2245 * SysV syntax applies.
2247 mf
->mf_next
= line_start
;
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.
2266 * Parse the mapfile.
2269 ld_map_parse(const char *mapfile
, Ofl_desc
*ofl
)
2271 struct stat stat_buf
; /* stat of mapfile */
2272 int mapfile_fd
; /* descriptor for mapfile */
2274 Mapfile
*mf
; /* Mapfile descriptor */
2275 size_t name_len
; /* strlen(mapfile) */
2278 * Determine if we're dealing with a file or a directory.
2280 if (stat(mapfile
, &stat_buf
) == -1) {
2282 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYS_STAT
), mapfile
,
2286 if (S_ISDIR(stat_buf
.st_mode
)) {
2288 struct dirent
*denp
;
2291 * Open the directory and interpret each visible file as a
2294 if ((dirp
= opendir(mapfile
)) == NULL
)
2297 while ((denp
= readdir(dirp
)) != NULL
) {
2298 char path
[PATH_MAX
];
2301 * Ignore any hidden filenames. Construct the full
2302 * pathname to the new mapfile.
2304 if (*denp
->d_name
== '.')
2306 (void) snprintf(path
, PATH_MAX
, MSG_ORIG(MSG_STR_PATH
),
2307 mapfile
, denp
->d_name
);
2308 if (!ld_map_parse(path
, ofl
))
2311 (void) closedir(dirp
);
2313 } else if (!S_ISREG(stat_buf
.st_mode
)) {
2314 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYS_NOTREG
), mapfile
);
2319 if ((mapfile_fd
= open(mapfile
, O_RDONLY
)) == -1) {
2321 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYS_OPEN
), mapfile
,
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.
2331 name_len
= strlen(mapfile
) + 1;
2332 mf
= libld_malloc(sizeof (*mf
) + name_len
+ stat_buf
.st_size
+ 1);
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
) !=
2342 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_SYS_READ
), mapfile
,
2344 (void) close(mapfile_fd
);
2347 (void) close(mapfile_fd
);
2348 mf
->mf_text
[stat_buf
.st_size
] = '\0';
2349 mf
->mf_next
= mf
->mf_text
;
2351 mf
->mf_next_ch
= 0; /* No "lookahead" character yet */
2352 mf
->mf_ec_insndx
= 0; /* Insert entrace criteria at top */
2355 * Read just enough from the mapfile to determine the version,
2356 * and then dispatch to the appropriate code for further processing
2358 if (!mapfile_version(mf
))
2362 * Start and continuation masks for unquoted identifier at this
2363 * mapfile version level.
2365 mf
->mf_tkid_start
= TKID_ATTR_START(mf
->mf_version
);
2366 mf
->mf_tkid_cont
= TKID_ATTR_CONT(mf
->mf_version
);
2368 DBG_CALL(Dbg_map_parse(ofl
->ofl_lml
, mapfile
, mf
->mf_version
));
2370 switch (mf
->mf_version
) {
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
);
2377 mf
->mf_tokdisp
= gettok_dispatch_v1
;
2378 if (!ld_map_parse_v1(mf
))
2383 mf
->mf_tokdisp
= gettok_dispatch_v2
;
2384 STACK_RESET(lms
.lms_cdir_stack
);
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.
2392 if ((lms
.lms_cexp_id
== NULL
) && !cexp_ident_init())
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.
2400 lms
.lms_cdir_valid
= 1;
2402 if (!ld_map_parse_v2(mf
))
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
);
2411 mf_fatal(mf
, MSG_INTL(MSG_MAP_CDIR_NOEND
),
2412 EC_LINENO(level
->cdl_if_lineno
));
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.
2426 * Only PT_LOAD segments can be assigned a virtual address. These segments can
2427 * be one of two types:
2429 * - Standard segments for text, data or bss. These segments will have been
2430 * inserted before the default text (first PT_LOAD) segment.
2432 * - Empty (reservation) segments. These segment will have been inserted at
2433 * the end of any default PT_LOAD segments.
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.
2439 * Any reservation segments are also sorted amoung themselves, as these segments
2440 * must still follow the standard default segments.
2443 sort_seg_list(Ofl_desc
*ofl
)
2445 APlist
*sort_segs
= NULL
, *load_segs
= NULL
;
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.
2456 nsegs
= aplist_nitems(ofl
->ofl_segs
);
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
)
2464 if (aplist_append(&sort_segs
, sgp1
, nsegs
) == NULL
)
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.
2473 for (APLIST_TRAVERSE(ofl
->ofl_segs_order
, idx1
, sgp1
)) {
2474 if (aplist_append(&sort_segs
, sgp1
, nsegs
) == NULL
)
2476 sgp1
->sg_flags
|= FLG_SG_ORDERED
;
2480 * Add the loadable segments to another list in sorted order.
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
));
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
))
2493 * If the loadable segment does not contain a vaddr, simply
2494 * append it to the new list.
2496 if ((sgp1
->sg_flags
& FLG_SG_P_VADDR
) == 0) {
2497 if (aplist_append(&load_segs
, sgp1
, AL_CNT_SEGMENTS
) ==
2507 * Traverse the segment list we are creating, looking
2508 * for a segment that defines a vaddr.
2510 for (APLIST_TRAVERSE(load_segs
, idx2
, sgp2
)) {
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
2518 if (((sgp2
->sg_flags
&
2519 (FLG_SG_P_VADDR
| FLG_SG_EMPTY
)) == 0) &&
2520 (sgp1
->sg_flags
& FLG_SG_EMPTY
))
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
),
2535 if (sgp1
->sg_phdr
.p_vaddr
>
2536 sgp2
->sg_phdr
.p_vaddr
)
2541 * Insert this segment before the segment on
2542 * the load_segs list.
2544 if (aplist_insert(&load_segs
, sgp1
,
2545 AL_CNT_SEGMENTS
, idx2
) == NULL
)
2552 * If the segment being inspected has not been inserted
2553 * in the segment list, simply append it to the list.
2555 if ((inserted
== 0) && (aplist_append(&load_segs
,
2556 sgp1
, AL_CNT_SEGMENTS
) == NULL
))
2562 * Add the sorted loadable segments to our initial segment list.
2564 for (APLIST_TRAVERSE(load_segs
, idx1
, sgp1
)) {
2565 if (aplist_append(&sort_segs
, sgp1
, AL_CNT_SEGMENTS
) == NULL
)
2570 * Add all other segments to our list.
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
))
2578 if (aplist_append(&sort_segs
, sgp1
, AL_CNT_SEGMENTS
) == NULL
)
2583 * Free the original list, and the pt_load list, and use
2584 * the new list as the segment list.
2586 free(ofl
->ofl_segs
);
2587 if (load_segs
) free(load_segs
);
2588 ofl
->ofl_segs
= sort_segs
;
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
);
2602 * After all mapfiles have been processed, this routine is used to
2603 * finish any remaining mapfile related work.
2606 * Returns TRUE on success, and FALSE on failure.
2609 ld_map_post_process(Ofl_desc
*ofl
)
2615 Sg_desc
*first_seg
= NULL
;
2618 DBG_CALL(Dbg_map_post_title(ofl
->ofl_lml
));
2621 * Per-segment processing:
2622 * - Identify segments with explicit virtual address
2623 * - Details of input and output section order
2625 for (APLIST_TRAVERSE(ofl
->ofl_segs
, idx
, sgp
)) {
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.
2632 if (sgp
->sg_name
== NULL
)
2635 /* Remember the first non-disabled segment */
2636 if ((first_seg
== NULL
) && !(sgp
->sg_flags
& FLG_SG_DISABLED
))
2640 * If a segment has an explicit virtual address, we will
2641 * need to sort the segments.
2643 if (sgp
->sg_flags
& FLG_SG_P_VADDR
)
2644 ofl
->ofl_flags1
|= FLG_OF1_VADDR
;
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.
2651 if (alist_nitems(sgp
->sg_os_order
) > 0)
2652 ofl
->ofl_flags
|= FLG_OF_OS_ORDER
;
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:
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
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.
2671 * Regardless of the syntax version used, the section sorting
2672 * code expects the following:
2674 * - Segments requiring input section sorting have the
2675 * FLG_SG_IS_ORDER flag set
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.
2681 * At this point, the following are true:
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
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.
2701 /* Version 1: ?O flag? */
2702 if (sgp
->sg_flags
& FLG_SG_IS_ORDER
) {
2705 ofl
->ofl_flags
|= FLG_OF_IS_ORDER
;
2706 DBG_CALL(Dbg_map_ent_ord_title(ofl
->ofl_lml
,
2710 * Give each user defined entrance criteria for this
2711 * segment that specifies a section name a
2712 * monotonically increasing sort key.
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
;
2722 /* Version 2: SEGMENT IS_ORDER list? */
2723 if (aplist_nitems(sgp
->sg_is_order
) > 0) {
2726 ofl
->ofl_flags
|= FLG_OF_IS_ORDER
;
2727 DBG_CALL(Dbg_map_ent_ord_title(ofl
->ofl_lml
,
2731 * Give each entrance criteria in the sg_is_order
2732 * list a monotonically increasing sort key.
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
;
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
))
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.
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
;
2756 if (ofl
->ofl_flags
& FLG_OF_RELOBJ
) {
2758 * NOHDR has no effect on a relocatable file.
2759 * Make sure this flag isn't set.
2761 ofl
->ofl_dtflags_1
&= ~DF_1_NOHDR
;
2762 } else if (first_seg
!= NULL
) {
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
2769 if ((ofl
->ofl_dtflags_1
& DF_1_NOHDR
) == 0) {
2771 * If we sorted the segments, the first segment
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
)
2779 if ((sgp
->sg_flags
& FLG_SG_DISABLED
) ==
2788 * If the per-segment NOHDR flag is set on our first
2789 * segment, then make it take effect.
2791 if (first_seg
->sg_flags
& FLG_SG_NOHDR
)
2792 ofl
->ofl_dtflags_1
|= DF_1_NOHDR
;
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
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
;
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
);
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).
2825 if (ofl
->ofl_maptext
|| ofl
->ofl_mapdata
)
2826 DBG_CALL(Dbg_sec_backing(ofl
->ofl_lml
));
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
)
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
)