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 }