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) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  27  */
  28 /*
  29  * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
  30  * Copyright 2017 RackTop Systems.
  31  */
  32 
  33 /*
  34  * Publicly available flags are defined in ld(1).   The following flags are
  35  * private, and may be removed at any time.
  36  *
  37  *    OPTION                    MEANING
  38  *
  39  *    -z dtrace=symbol          assigns symbol to PT_SUNWDTRACE segment,
  40  *                              providing scratch area for dtrace processing.
  41  *
  42  *    -z noreloc                suppress relocation processing.  This provides
  43  *                              a mechanism for validating kernel module symbol
  44  *                              resolution that would normally incur fatal
  45  *                              relocation errors.
  46  *
  47  *    -z rtldinfo=symbol        assigns symbol to SUNW_RTLDINF dynamic tag,
  48  *                              providing pre-initialization specific routines
  49  *                              for TLS initialization.
  50  *
  51  *    -z nointerp               suppress the addition of an interpreter
  52  *                              section.  This is used to generate the kernel,
  53  *                              but makes no sense to be used by anyone else.
  54  *
  55  *    -z norelaxreloc           suppress the automatic addition of relaxed
  56  *                              relocations to GNU linkonce/COMDAT sections.
  57  *
  58  *    -z nosighandler           suppress the registration of the signal handler
  59  *                              used to manage SIGBUS.
  60  */
  61 
  62 /*
  63  * The following flags are committed, and will not be removed, but are
  64  * not publically documented, either because they are obsolete, or because
  65  * they exist to work around defects in other software and are not of
  66  * sufficient interest otherwise.
  67  *
  68  *    OPTION                    MEANING
  69  *
  70  *    -Wl,...                   compiler drivers and configuration tools
  71  *                              have been known to pass this compiler option
  72  *                              to ld(1).  Strip off the "-Wl," prefix and
  73  *                              process the remainder (...) as a normal option.
  74  */
  75 
  76 #include        <sys/link.h>
  77 #include        <stdio.h>
  78 #include        <fcntl.h>
  79 #include        <string.h>
  80 #include        <errno.h>
  81 #include        <elf.h>
  82 #include        <unistd.h>
  83 #include        <debug.h>
  84 #include        "msg.h"
  85 #include        "_libld.h"
  86 
  87 /*
  88  * Define a set of local argument flags, the settings of these will be
  89  * verified in check_flags() and lead to the appropriate output file flags
  90  * being initialized.
  91  */
  92 typedef enum {
  93         SET_UNKNOWN = -1,
  94         SET_FALSE = 0,
  95         SET_TRUE = 1
  96 } Setstate;
  97 
  98 static Setstate dflag   = SET_UNKNOWN;
  99 static Setstate zdflag  = SET_UNKNOWN;
 100 static Setstate Qflag   = SET_UNKNOWN;
 101 static Setstate Bdflag  = SET_UNKNOWN;
 102 static Setstate zfwflag = SET_UNKNOWN;
 103 
 104 static Boolean  aflag   = FALSE;
 105 static Boolean  bflag   = FALSE;
 106 static Boolean  rflag   = FALSE;
 107 static Boolean  sflag   = FALSE;
 108 static Boolean  zinflag = FALSE;
 109 static Boolean  zlflag  = FALSE;
 110 static Boolean  Bgflag  = FALSE;
 111 static Boolean  Blflag  = FALSE;
 112 static Boolean  Beflag  = FALSE;
 113 static Boolean  Bsflag  = FALSE;
 114 static Boolean  Dflag   = FALSE;
 115 static Boolean  Gflag   = FALSE;
 116 static Boolean  Vflag   = FALSE;
 117 
 118 /*
 119  * ztflag's state is set by pointing it to the matching string:
 120  *      text | textoff | textwarn
 121  */
 122 static const char       *ztflag = NULL;
 123 
 124 /*
 125  * Remember the guidance flags that result from the initial -z guidance
 126  * option, so that they can be compared to any that follow. We only want
 127  * to issue a warning when they differ.
 128  */
 129 static ofl_guideflag_t  initial_guidance_flags  = 0;
 130 
 131 static uintptr_t process_files_com(Ofl_desc *, int, char **);
 132 static uintptr_t process_flags_com(Ofl_desc *, int, char **, int *);
 133 
 134 /*
 135  * Print usage message to stderr - 2 modes, summary message only,
 136  * and full usage message.
 137  */
 138 static void
 139 usage_mesg(Boolean detail)
 140 {
 141         (void) fprintf(stderr, MSG_INTL(MSG_ARG_USAGE),
 142             MSG_ORIG(MSG_STR_OPTIONS));
 143 
 144         if (detail == FALSE)
 145                 return;
 146 
 147         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_3));
 148         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_6));
 149         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_A));
 150         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_B));
 151         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDR));
 152         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDY));
 153         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBE));
 154         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBG));
 155         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBL));
 156         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBR));
 157         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBS));
 158         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_C));
 159         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CC));
 160         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_D));
 161         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CD));
 162         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_E));
 163         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_F));
 164         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CF));
 165         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CG));
 166         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_H));
 167         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_I));
 168         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CI));
 169         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_L));
 170         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CL));
 171         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_M));
 172         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CM));
 173         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CN));
 174         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_O));
 175         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_P));
 176         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CP));
 177         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CQ));
 178         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_R));
 179         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CR));
 180         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_S));
 181         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CS));
 182         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_T));
 183         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_U));
 184         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CV));
 185         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY));
 186         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA));
 187         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
 188         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL));
 189         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZADLIB));
 190         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
 191         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDEF));
 192         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
 193         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
 194         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
 195         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFATW));
 196         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFA));
 197         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGP));
 198         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGUIDE));
 199         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZH));
 200         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZIG));
 201         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINA));
 202         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINI));
 203         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINT));
 204         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLAZY));
 205         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD32));
 206         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD64));
 207         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLO));
 208         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZM));
 209         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNC));
 210         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDFS));
 211         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEF));
 212         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEL));
 213         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDLO));
 214         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDU));
 215         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNLD));
 216         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNOW));
 217         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNPA));
 218         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNV));
 219         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZO));
 220         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZPIA));
 221         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRL));
 222         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRREL));
 223         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRS));
 224         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSN));
 225         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSGRP));
 226         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZSCAP));
 227         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTARG));
 228         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT));
 229         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO));
 230         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW));
 231         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZWRAP));
 232         (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZVER));
 233 }
 234 
 235 /*
 236  * Rescan the archives seen on the command line in order
 237  * to handle circularly dependent archives, stopping when
 238  * no further member extraction occurs.
 239  *
 240  * entry:
 241  *      ofl - Output file descriptor
 242  *      isgrp - True if this is a an archive group search, False
 243  *              to search starting with argv[1] through end_arg_ndx
 244  *      end_arg_ndx - Index of final argv element to consider.
 245  */
 246 static uintptr_t
 247 ld_rescan_archives(Ofl_desc *ofl, int isgrp, int end_arg_ndx)
 248 {
 249         ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
 250 
 251         while (ofl->ofl_flags1 & FLG_OF1_EXTRACT) {
 252                 Aliste          idx;
 253                 Ar_desc         *adp;
 254                 Word            start_ndx = isgrp ? ofl->ofl_ars_gsndx : 0;
 255                 Word            ndx = 0;
 256 
 257                 ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT;
 258 
 259                 DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml,
 260                     isgrp ? ofl->ofl_ars_gsandx : 1, end_arg_ndx));
 261 
 262                 for (APLIST_TRAVERSE(ofl->ofl_ars, idx, adp)) {
 263                         /* If not to starting index yet, skip it */
 264                         if (ndx++ < start_ndx)
 265                                 continue;
 266 
 267                         /*
 268                          * If this archive was processed with -z allextract,
 269                          * then all members have already been extracted.
 270                          */
 271                         if (adp->ad_elf == NULL)
 272                                 continue;
 273 
 274                         /*
 275                          * Reestablish any archive specific command line flags.
 276                          */
 277                         ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE;
 278                         ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE);
 279 
 280                         /*
 281                          * Re-process the archive.  Note that a file descriptor
 282                          * is unnecessary, as the file is already available in
 283                          * memory.
 284                          */
 285                         if (!ld_process_archive(adp->ad_name, -1, adp, ofl))
 286                                 return (S_ERROR);
 287                         if (ofl->ofl_flags & FLG_OF_FATAL)
 288                                 return (1);
 289                 }
 290         }
 291 
 292         return (1);
 293 }
 294 
 295 /*
 296  * Checks the command line option flags for consistency.
 297  */
 298 static uintptr_t
 299 check_flags(Ofl_desc * ofl, int argc)
 300 {
 301         /*
 302          * If the user specified -zguidance=noall, then we can safely disable
 303          * the entire feature. The purpose of -zguidance=noall is to allow
 304          * the user to override guidance specified from a makefile via
 305          * the LD_OPTIONS environment variable, and so, we want to behave
 306          * in exactly the same manner we would have if no option were present.
 307          */
 308         if ((ofl->ofl_guideflags & (FLG_OFG_ENABLE | FLG_OFG_NO_ALL)) ==
 309             (FLG_OFG_ENABLE | FLG_OFG_NO_ALL))
 310                 ofl->ofl_guideflags &= ~FLG_OFG_ENABLE;
 311 
 312         if (Plibpath && (Llibdir || Ulibdir))
 313                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
 314                     Llibdir ? 'L' : 'U');
 315 
 316         if (rflag) {
 317                 if (dflag == SET_UNKNOWN)
 318                         dflag = SET_FALSE;
 319                 /*
 320                  * Combining relocations when building a relocatable
 321                  * object isn't allowed.  Warn the user, but proceed.
 322                  */
 323                 if (ofl->ofl_flags & FLG_OF_COMREL)
 324                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP),
 325                             MSG_INTL(MSG_MARG_REL),
 326                             MSG_ORIG(MSG_ARG_ZCOMBRELOC));
 327                 ofl->ofl_flags |= FLG_OF_RELOBJ;
 328         } else {
 329                 /*
 330                  * Translating object capabilities to symbol capabilities is
 331                  * only meaningful when creating a relocatable object.
 332                  */
 333                 if (ofl->ofl_flags & FLG_OF_OTOSCAP)
 334                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ONLY),
 335                             MSG_ORIG(MSG_ARG_ZSYMBOLCAP),
 336                             MSG_INTL(MSG_MARG_REL));
 337 
 338                 /*
 339                  * If the user hasn't explicitly requested that relocations
 340                  * not be combined, combine them by default.
 341                  */
 342                 if ((ofl->ofl_flags & FLG_OF_NOCOMREL) == 0)
 343                         ofl->ofl_flags |= FLG_OF_COMREL;
 344         }
 345 
 346         if (zdflag == SET_TRUE)
 347                 ofl->ofl_flags |= FLG_OF_NOUNDEF;
 348 
 349         if (zinflag)
 350                 ofl->ofl_dtflags_1 |= DF_1_INTERPOSE;
 351 
 352         if (sflag)
 353                 ofl->ofl_flags |= FLG_OF_STRIP;
 354 
 355         if (Qflag == SET_TRUE)
 356                 ofl->ofl_flags |= FLG_OF_ADDVERS;
 357 
 358         if (Blflag)
 359                 ofl->ofl_flags |= FLG_OF_AUTOLCL;
 360 
 361         if (Beflag)
 362                 ofl->ofl_flags |= FLG_OF_AUTOELM;
 363 
 364         if (Blflag && Beflag)
 365                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 366                     MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL));
 367 
 368         if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP))
 369                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 370                     MSG_ORIG(MSG_ARG_CI), MSG_ORIG(MSG_ARG_ZNOINTERP));
 371 
 372         if ((ofl->ofl_flags1 & (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ==
 373             (FLG_OF1_NRLXREL | FLG_OF1_RLXREL))
 374                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 375                     MSG_ORIG(MSG_ARG_ZRELAXRELOC),
 376                     MSG_ORIG(MSG_ARG_ZNORELAXRELOC));
 377 
 378         if (ofl->ofl_filtees && !Gflag)
 379                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL),
 380                     ((ofl->ofl_flags & FLG_OF_AUX) ?
 381                     MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER)));
 382 
 383         if (dflag != SET_FALSE) {
 384                 /*
 385                  * Set -Bdynamic on by default, setting is rechecked as input
 386                  * files are processed.
 387                  */
 388                 ofl->ofl_flags |=
 389                     (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED);
 390 
 391                 if (aflag)
 392                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 393                             MSG_ORIG(MSG_ARG_DY), MSG_ORIG(MSG_ARG_A));
 394 
 395                 if (bflag)
 396                         ofl->ofl_flags |= FLG_OF_BFLAG;
 397 
 398                 if (Bgflag == TRUE) {
 399                         if (zdflag == SET_FALSE)
 400                                 ld_eprintf(ofl, ERR_FATAL,
 401                                     MSG_INTL(MSG_ARG_INCOMP),
 402                                     MSG_ORIG(MSG_ARG_BGROUP),
 403                                     MSG_ORIG(MSG_ARG_ZNODEF));
 404                         ofl->ofl_dtflags_1 |= DF_1_GROUP;
 405                         ofl->ofl_flags |= FLG_OF_NOUNDEF;
 406                 }
 407 
 408                 /*
 409                  * If the use of default library searching has been suppressed
 410                  * but no runpaths have been provided we're going to have a hard
 411                  * job running this object.
 412                  */
 413                 if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath)
 414                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ARG_NODEFLIB),
 415                             MSG_INTL(MSG_MARG_RPATH));
 416 
 417                 /*
 418                  * By default, text relocation warnings are given when building
 419                  * an executable unless the -b flag is specified.  This option
 420                  * implies that unclean text can be created, so no warnings are
 421                  * generated unless specifically asked for.
 422                  */
 423                 if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) ||
 424                     ((ztflag == NULL) && bflag)) {
 425                         ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
 426                         ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 427                 } else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) {
 428                         ofl->ofl_flags |= FLG_OF_PURETXT;
 429                         ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 430                 }
 431 
 432                 if (Gflag || !rflag) {
 433                         /*
 434                          * Create a dynamic object.  -Bdirect indicates that all
 435                          * references should be bound directly.  This also
 436                          * enables lazyloading.  Individual symbols can be
 437                          * bound directly (or not) using mapfiles and the
 438                          * DIRECT (NODIRECT) qualifier.  With this capability,
 439                          * each syminfo entry is tagged SYMINFO_FLG_DIRECTBIND.
 440                          * Prior to this per-symbol direct binding, runtime
 441                          * direct binding was controlled via the DF_1_DIRECT
 442                          * flag.  This flag affected all references from the
 443                          * object.  -Bdirect continues to set this flag, and
 444                          * thus provides a means of taking a newly built
 445                          * direct binding object back to older systems.
 446                          *
 447                          * NOTE, any use of per-symbol NODIRECT bindings, or
 448                          * -znodirect, will disable the creation of the
 449                          * DF_1_DIRECT flag.  Older runtime linkers do not
 450                          * have the capability to do per-symbol direct bindings.
 451                          */
 452                         if (Bdflag == SET_TRUE) {
 453                                 ofl->ofl_dtflags_1 |= DF_1_DIRECT;
 454                                 ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
 455                                 ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
 456                                 ofl->ofl_flags |= FLG_OF_SYMINFO;
 457                         }
 458 
 459                         /*
 460                          * -Bnodirect disables directly binding to any symbols
 461                          * exported from the object being created.  Individual
 462                          * references to external objects can still be affected
 463                          * by -zdirect or mapfile DIRECT directives.
 464                          */
 465                         if (Bdflag == SET_FALSE) {
 466                                 ofl->ofl_flags1 |= (FLG_OF1_NDIRECT |
 467                                     FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR);
 468                                 ofl->ofl_flags |= FLG_OF_SYMINFO;
 469                         }
 470                 }
 471 
 472                 if (!Gflag && !rflag) {
 473                         /*
 474                          * Dynamically linked executable.
 475                          */
 476                         ofl->ofl_flags |= FLG_OF_EXEC;
 477 
 478                         if (zdflag != SET_FALSE)
 479                                 ofl->ofl_flags |= FLG_OF_NOUNDEF;
 480 
 481                         /*
 482                          * -z textwarn is the default for executables, and
 483                          * only an explicit -z text* option can change that,
 484                          * so there's no need to provide additional guidance.
 485                          */
 486                         ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 487 
 488                         if (Bsflag)
 489                                 ld_eprintf(ofl, ERR_FATAL,
 490                                     MSG_INTL(MSG_ARG_DY_INCOMP),
 491                                     MSG_ORIG(MSG_ARG_BSYMBOLIC));
 492                         if (ofl->ofl_soname)
 493                                 ld_eprintf(ofl, ERR_FATAL,
 494                                     MSG_INTL(MSG_MARG_DY_INCOMP),
 495                                     MSG_INTL(MSG_MARG_SONAME));
 496                 } else if (!rflag) {
 497                         /*
 498                          * Shared library.
 499                          */
 500                         ofl->ofl_flags |= FLG_OF_SHAROBJ;
 501 
 502                         /*
 503                          * By default, print text relocation warnings for
 504                          * executables but *not* for shared objects. However,
 505                          * if -z guidance is on, issue warnings for shared
 506                          * objects as well.
 507                          *
 508                          * If -z textwarn is explicitly specified, also issue
 509                          * guidance messages if -z guidance is on, but not
 510                          * for -z text or -z textoff.
 511                          */
 512                         if (ztflag == NULL) {
 513                                 if (!OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
 514                                         ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
 515                         } else if ((ofl->ofl_flags & FLG_OF_PURETXT) ||
 516                             (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)) {
 517                                 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 518                         }
 519 
 520                         if (Bsflag) {
 521                                 /*
 522                                  * -Bsymbolic, and -Bnodirect make no sense.
 523                                  */
 524                                 if (Bdflag == SET_FALSE)
 525                                         ld_eprintf(ofl, ERR_FATAL,
 526                                             MSG_INTL(MSG_ARG_INCOMP),
 527                                             MSG_ORIG(MSG_ARG_BSYMBOLIC),
 528                                             MSG_ORIG(MSG_ARG_BNODIRECT));
 529                                 ofl->ofl_flags |= FLG_OF_SYMBOLIC;
 530                                 ofl->ofl_dtflags |= DF_SYMBOLIC;
 531                         }
 532                 } else {
 533                         /*
 534                          * Dynamic relocatable object.
 535                          */
 536                         if (ztflag == NULL)
 537                                 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
 538                         ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 539 
 540                         if (ofl->ofl_interp)
 541                                 ld_eprintf(ofl, ERR_FATAL,
 542                                     MSG_INTL(MSG_MARG_INCOMP),
 543                                     MSG_INTL(MSG_MARG_REL),
 544                                     MSG_ORIG(MSG_ARG_CI));
 545                 }
 546         } else {
 547                 ofl->ofl_flags |= FLG_OF_STATIC;
 548 
 549                 if (bflag)
 550                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 551                             MSG_ORIG(MSG_ARG_B));
 552                 if (ofl->ofl_soname)
 553                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
 554                             MSG_INTL(MSG_MARG_SONAME));
 555                 if (ofl->ofl_depaudit)
 556                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 557                             MSG_ORIG(MSG_ARG_CP));
 558                 if (ofl->ofl_audit)
 559                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 560                             MSG_ORIG(MSG_ARG_P));
 561                 if (ofl->ofl_config)
 562                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 563                             MSG_ORIG(MSG_ARG_C));
 564                 if (ztflag)
 565                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 566                             MSG_ORIG(MSG_ARG_ZTEXTALL));
 567                 if (Gflag)
 568                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
 569                             MSG_INTL(MSG_MARG_SO));
 570                 if (aflag && rflag)
 571                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP),
 572                             MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL));
 573 
 574                 if (rflag) {
 575                         /*
 576                          * We can only strip the symbol table and string table
 577                          * if no output relocations will refer to them.
 578                          */
 579                         if (sflag)
 580                                 ld_eprintf(ofl, ERR_WARNING,
 581                                     MSG_INTL(MSG_ARG_STRIP),
 582                                     MSG_INTL(MSG_MARG_REL),
 583                                     MSG_INTL(MSG_MARG_STRIP));
 584 
 585                         if (ztflag == NULL)
 586                                 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
 587                         ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 588 
 589                         if (ofl->ofl_interp)
 590                                 ld_eprintf(ofl, ERR_FATAL,
 591                                     MSG_INTL(MSG_MARG_INCOMP),
 592                                     MSG_INTL(MSG_MARG_REL),
 593                                     MSG_ORIG(MSG_ARG_CI));
 594                 } else {
 595                         /*
 596                          * Static executable.
 597                          */
 598                         ofl->ofl_flags |= FLG_OF_EXEC | FLG_OF_PROCRED;
 599 
 600                         if (zdflag != SET_FALSE)
 601                                 ofl->ofl_flags |= FLG_OF_NOUNDEF;
 602                 }
 603         }
 604 
 605         /*
 606          * If the user didn't supply an output file name supply a default.
 607          */
 608         if (ofl->ofl_name == NULL)
 609                 ofl->ofl_name = MSG_ORIG(MSG_STR_AOUT);
 610 
 611         /*
 612          * We set the entrance criteria after all input argument processing as
 613          * it is only at this point we're sure what the output image will be
 614          * (static or dynamic).
 615          */
 616         if (ld_ent_setup(ofl, ld_targ.t_m.m_segm_align) == S_ERROR)
 617                 return (S_ERROR);
 618 
 619         /*
 620          * Does the host currently running the linker have the same
 621          * byte order as the target for which the object is being produced?
 622          * If not, set FLG_OF1_ENCDIFF so relocation code will know
 623          * to check.
 624          */
 625         if (_elf_sys_encoding() != ld_targ.t_m.m_data)
 626                 ofl->ofl_flags1 |= FLG_OF1_ENCDIFF;
 627 
 628         /*
 629          * If the target has special executable section filling requirements,
 630          * register the fill function with libelf
 631          */
 632         if (ld_targ.t_ff.ff_execfill != NULL)
 633                 _elf_execfill(ld_targ.t_ff.ff_execfill);
 634 
 635         /*
 636          * Initialize string tables.  Symbol definitions within mapfiles can
 637          * result in the creation of input sections.
 638          */
 639         if (ld_init_strings(ofl) == S_ERROR)
 640                 return (S_ERROR);
 641 
 642         /*
 643          * Process mapfiles. Mapfile can redefine or add sections/segments,
 644          * so this must come after the default entrance criteria are established
 645          * (above).
 646          */
 647         if (ofl->ofl_maps) {
 648                 const char      *name;
 649                 Aliste          idx;
 650 
 651                 for (APLIST_TRAVERSE(ofl->ofl_maps, idx, name))
 652                         if (!ld_map_parse(name, ofl))
 653                                 return (S_ERROR);
 654 
 655                 if (!ld_map_post_process(ofl))
 656                         return (S_ERROR);
 657         }
 658 
 659         /*
 660          * If a mapfile has been used to define a single symbolic scope of
 661          * interfaces, -Bsymbolic is established.  This global setting goes
 662          * beyond individual symbol protection, and ensures all relocations
 663          * (even those that reference section symbols) are processed within
 664          * the object being built.
 665          */
 666         if (((ofl->ofl_flags &
 667             (FLG_OF_MAPSYMB | FLG_OF_MAPGLOB)) == FLG_OF_MAPSYMB) &&
 668             (ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM))) {
 669                 ofl->ofl_flags |= FLG_OF_SYMBOLIC;
 670                 ofl->ofl_dtflags |= DF_SYMBOLIC;
 671         }
 672 
 673         /*
 674          * If -zloadfltr is set, verify that filtering is in effect.  Filters
 675          * are either established from the command line, and affect the whole
 676          * object, or are set on a per-symbol basis from a mapfile.
 677          */
 678         if (zlflag) {
 679                 if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL))
 680                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFLTR),
 681                             MSG_ORIG(MSG_ARG_ZLOADFLTR));
 682                 ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
 683         }
 684 
 685         /*
 686          * Check that we have something to work with. This check is carried out
 687          * after mapfile processing as its possible a mapfile is being used to
 688          * define symbols, in which case it would be sufficient to build the
 689          * output file purely from the mapfile.
 690          */
 691         if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
 692                 if ((Vflag ||
 693                     (Dflag && (dbg_desc->d_extra & DBG_E_HELP_EXIT))) &&
 694                     (argc == 2)) {
 695                         ofl->ofl_flags1 |= FLG_OF1_DONE;
 696                 } else {
 697                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFILES));
 698                         return (S_ERROR);
 699                 }
 700         }
 701         return (1);
 702 }
 703 
 704 /*
 705  * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
 706  * used as an argument to getopt().
 707  *
 708  * If the second argument 'usage' is not NULL, then this is called from the
 709  * first pass. Else this is called from the second pass.
 710  */
 711 static uintptr_t
 712 createargv(Ofl_desc *ofl, int *usage)
 713 {
 714         int             argc = 0, idx = 0, ooptind;
 715         uintptr_t       ret;
 716         char            **argv, *p0;
 717 
 718         /*
 719          * The argument being examined is either:
 720          *      ld32=   or
 721          *      ld64=
 722          */
 723 #if     defined(_LP64)
 724         if (optarg[2] == '3')
 725                 return (0);
 726 #else
 727         if (optarg[2] == '6')
 728                 return (0);
 729 #endif
 730 
 731         p0 = &optarg[5];
 732 
 733         /*
 734          * Count the number of arguments.
 735          */
 736         while (*p0) {
 737                 /*
 738                  * Pointing at non-separator character.
 739                  */
 740                 if (*p0 != ',') {
 741                         argc++;
 742                         while (*p0 && (*p0 != ','))
 743                                 p0++;
 744                         continue;
 745                 }
 746 
 747                 /*
 748                  * Pointing at a separator character.
 749                  */
 750                 if (*p0 == ',') {
 751                         while (*p0 == ',')
 752                                 p0++;
 753                         continue;
 754                 }
 755         }
 756 
 757         if (argc == 0)
 758                 return (0);
 759 
 760         /*
 761          * Allocate argument vector.
 762          */
 763         if ((p0 = (char *)strdup(&optarg[5])) == NULL)
 764                 return (S_ERROR);
 765         if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == NULL)
 766                 return (S_ERROR);
 767 
 768         while (*p0) {
 769                 char *p;
 770 
 771                 /*
 772                  * Pointing at the beginning of non-separator character string.
 773                  */
 774                 if (*p0 != ',') {
 775                         p = p0;
 776                         while (*p0 && (*p0 != ','))
 777                                 p0++;
 778                         argv[idx++] = p;
 779                         if (*p0) {
 780                                 *p0 = '\0';
 781                                 p0++;
 782                         }
 783                         continue;
 784                 }
 785 
 786                 /*
 787                  * Pointing at the beginining of separator character string.
 788                  */
 789                 if (*p0 == ',') {
 790                         while (*p0 == ',')
 791                                 p0++;
 792                         continue;
 793                 }
 794         }
 795         argv[idx] = 0;
 796         ooptind = optind;
 797         optind = 0;
 798 
 799         /*
 800          * Dispatch to pass1 or pass2
 801          */
 802         if (usage)
 803                 ret = process_flags_com(ofl, argc, argv, usage);
 804         else
 805                 ret = process_files_com(ofl, argc, argv);
 806 
 807         optind = ooptind;
 808         return (ret);
 809 }
 810 
 811 /*
 812  * Parse the items in a '-z guidance' value, and set the ofl_guideflags.
 813  * A guidance option looks like this:
 814  *
 815  *      -z guidance[=item1,item2,...]
 816  *
 817  * Where each item specifies categories of guidance messages to suppress,
 818  * each starting with the prefix 'no'. We allow arbitrary whitespace between
 819  * the items, allow multiple ',' delimiters without an intervening item, and
 820  * quietly ignore any items we don't recognize.
 821  *
 822  * -    Such items are likely to be known to newer versions of the linker,
 823  *      and we do not want an older version of the linker to
 824  *      complain about them.
 825  *
 826  * -    Times and standards can change, and so we wish to reserve the
 827  *      right to make an old item that no longer makes sense go away.
 828  *      Quietly ignoring unrecognized items facilitates this.
 829  *
 830  * However, we always display unrecognized items in debug output.
 831  *
 832  * entry:
 833  *      ofl - Output descriptor
 834  *      optarg - option string to be processed. This will either be a NULL
 835  *              terminated 'guidance', or it will be 'guidance=' followed
 836  *              by the item tokens as described above.
 837  *
 838  * exit:
 839  *      Returns TRUE (1) on success, FALSE (0) on failure.
 840  *
 841  */
 842 static Boolean
 843 guidance_parse(Ofl_desc *ofl, char *optarg)
 844 {
 845         typedef struct {
 846                 const char      *name;
 847                 ofl_guideflag_t flag;
 848         } item_desc;
 849 
 850         static  item_desc items[] = {
 851                 { MSG_ORIG(MSG_ARG_GUIDE_NO_ALL),       FLG_OFG_NO_ALL },
 852 
 853                 { MSG_ORIG(MSG_ARG_GUIDE_NO_DEFS),      FLG_OFG_NO_DEFS },
 854                 { MSG_ORIG(MSG_ARG_GUIDE_NO_DIRECT),    FLG_OFG_NO_DB },
 855                 { MSG_ORIG(MSG_ARG_GUIDE_NO_LAZYLOAD),  FLG_OFG_NO_LAZY },
 856                 { MSG_ORIG(MSG_ARG_GUIDE_NO_MAPFILE),   FLG_OFG_NO_MF },
 857                 { MSG_ORIG(MSG_ARG_GUIDE_NO_TEXT),      FLG_OFG_NO_TEXT },
 858                 { MSG_ORIG(MSG_ARG_GUIDE_NO_UNUSED),    FLG_OFG_NO_UNUSED },
 859                 { NULL,                                 0 }
 860         };
 861 
 862         char            *lasts, *name;
 863         item_desc       *item;
 864         ofl_guideflag_t ofl_guideflags = FLG_OFG_ENABLE;
 865 
 866         /*
 867          * Skip the 'guidance' prefix. If NULL terminated, there are no
 868          * item values to parse. Otherwise, skip the '=' and parse the items.
 869          */
 870         optarg += MSG_ARG_GUIDE_SIZE;
 871         if (*optarg == '=') {
 872                 optarg++;
 873 
 874                 if ((name = libld_malloc(strlen(optarg) + 1)) == NULL)
 875                         return (FALSE);
 876                 (void) strcpy(name, optarg);
 877 
 878                 if ((name = strtok_r(name, MSG_ORIG(MSG_ARG_GUIDE_DELIM),
 879                     &lasts)) != NULL) {
 880                         do {
 881                                 for (item = items; item->name != NULL; item++)
 882                                         if (strcasecmp(name, item->name) == 0)
 883                                                 break;
 884                                 if (item->name == NULL) {
 885                                         DBG_CALL(Dbg_args_guidance_unknown(
 886                                             ofl->ofl_lml, name));
 887                                         continue;
 888                                 }
 889                                 ofl_guideflags |= item->flag;
 890                         } while ((name = strtok_r(NULL,
 891                             MSG_ORIG(MSG_ARG_GUIDE_DELIM), &lasts)) != NULL);
 892                 }
 893         }
 894 
 895         /*
 896          * If -zguidance is used more than once, we take the first one. We
 897          * do this quietly if they have identical options, and with a warning
 898          * otherwise.
 899          */
 900         if ((initial_guidance_flags & FLG_OFG_ENABLE) &&
 901             (ofl_guideflags != initial_guidance_flags)) {
 902                 ld_eprintf(ofl, ERR_WARNING_NF, MSG_INTL(MSG_ARG_MTONCE),
 903                     MSG_ORIG(MSG_ARG_ZGUIDE));
 904                 return (TRUE);
 905         }
 906 
 907         /*
 908          * First time: Save the flags for comparison to any subsequent
 909          * -z guidance that comes along, and OR the resulting flags into
 910          * the flags kept in the output descriptor.
 911          */
 912         initial_guidance_flags = ofl_guideflags;
 913         ofl->ofl_guideflags |= ofl_guideflags;
 914         return (TRUE);
 915 }
 916 
 917 /*
 918  * Parse the -z assert-deflib option. This option can appear in two different
 919  * forms:
 920  *      -z assert-deflib
 921  *      -z assert-deflib=libfred.so
 922  *
 923  * Either form enables this option, the latter form marks libfred.so as an
 924  * exempt library from the check. It is valid to have multiple invocations of
 925  * the second form. We silently ignore mulitple occurrences of the first form
 926  * and multiple invocations of the first form when the second form also occurs.
 927  *
 928  * We only return false when we have an internal error, such as the failure of
 929  * aplist_append. Every other time we return true, but we have the appropriate
 930  * fatal flags set beacuse of the ld_eprintf.
 931  */
 932 static int
 933 assdeflib_parse(Ofl_desc *ofl, char *optarg)
 934 {
 935         size_t olen, mlen;
 936         ofl->ofl_flags |= FLG_OF_ADEFLIB;
 937 
 938         olen = strlen(optarg);
 939         /* Minimum size of assert-deflib=lib%s.so */
 940         mlen = MSG_ARG_ASSDEFLIB_SIZE + 1 + MSG_STR_LIB_SIZE +
 941             MSG_STR_SOEXT_SIZE;
 942         if (olen > MSG_ARG_ASSDEFLIB_SIZE) {
 943                 if (optarg[MSG_ARG_ASSDEFLIB_SIZE] != '=') {
 944                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ILLEGAL),
 945                             MSG_ORIG(MSG_ARG_ASSDEFLIB), optarg);
 946                         return (TRUE);
 947                 }
 948 
 949                 if (strncmp(optarg + MSG_ARG_ASSDEFLIB_SIZE + 1,
 950                     MSG_ORIG(MSG_STR_LIB), MSG_STR_LIB_SIZE) != 0 ||
 951                     strcmp(optarg + olen - MSG_STR_SOEXT_SIZE,
 952                     MSG_ORIG(MSG_STR_SOEXT)) != 0 || olen <= mlen) {
 953                         ld_eprintf(ofl, ERR_FATAL,
 954                             MSG_INTL(MSG_ARG_ASSDEFLIB_MALFORMED), optarg);
 955                         return (TRUE);
 956                 }
 957 
 958                 if (aplist_append(&ofl->ofl_assdeflib, optarg +
 959                     MSG_ARG_ASSDEFLIB_SIZE + 1, AL_CNT_ASSDEFLIB) == NULL)
 960                         return (FALSE);
 961         }
 962 
 963         return (TRUE);
 964 }
 965 
 966 static int      optitle = 0;
 967 /*
 968  * Parsing options pass1 for process_flags().
 969  */
 970 static uintptr_t
 971 parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
 972 {
 973         int     c, ndx = optind;
 974 
 975         /*
 976          * The -32, -64 and -ztarget options are special, in that we validate
 977          * them, but otherwise ignore them. libld.so (this code) is called
 978          * from the ld front end program. ld has already examined the
 979          * arguments to determine the output class and machine type of the
 980          * output object, as reflected in the version (32/64) of ld_main()
 981          * that was called and the value of the 'mach' argument passed.
 982          * By time execution reaches this point, these options have already
 983          * been seen and acted on.
 984          */
 985         while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
 986 
 987                 switch (c) {
 988                 case '3':
 989                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 990 
 991                         /*
 992                          * -32 is processed by ld to determine the output class.
 993                          * Here we sanity check the option incase some other
 994                          * -3* option is mistakenly passed to us.
 995                          */
 996                         if (optarg[0] != '2')
 997                                 ld_eprintf(ofl, ERR_FATAL,
 998                                     MSG_INTL(MSG_ARG_ILLEGAL),
 999                                     MSG_ORIG(MSG_ARG_3), optarg);
1000                         continue;
1001 
1002                 case '6':
1003                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1004 
1005                         /*
1006                          * -64 is processed by ld to determine the output class.
1007                          * Here we sanity check the option incase some other
1008                          * -6* option is mistakenly passed to us.
1009                          */
1010                         if (optarg[0] != '4')
1011                                 ld_eprintf(ofl, ERR_FATAL,
1012                                     MSG_INTL(MSG_ARG_ILLEGAL),
1013                                     MSG_ORIG(MSG_ARG_6), optarg);
1014                         continue;
1015 
1016                 case 'a':
1017                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1018                         aflag = TRUE;
1019                         break;
1020 
1021                 case 'b':
1022                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1023                         bflag = TRUE;
1024 
1025                         /*
1026                          * This is a hack, and may be undone later.
1027                          * The -b option is only used to build the Unix
1028                          * kernel and its related kernel-mode modules.
1029                          * We do not want those files to get a .SUNW_ldynsym
1030                          * section. At least for now, the kernel makes no
1031                          * use of .SUNW_ldynsym, and we do not want to use
1032                          * the space to hold it. Therefore, we overload
1033                          * the use of -b to also imply -znoldynsym.
1034                          */
1035                         ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1036                         break;
1037 
1038                 case 'c':
1039                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1040                         if (ofl->ofl_config)
1041                                 ld_eprintf(ofl, ERR_WARNING_NF,
1042                                     MSG_INTL(MSG_ARG_MTONCE),
1043                                     MSG_ORIG(MSG_ARG_C));
1044                         else
1045                                 ofl->ofl_config = optarg;
1046                         break;
1047 
1048                 case 'C':
1049                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1050                         demangle_flag = 1;
1051                         break;
1052 
1053                 case 'd':
1054                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1055                         if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1056                                 if (dflag != SET_UNKNOWN)
1057                                         ld_eprintf(ofl, ERR_WARNING_NF,
1058                                             MSG_INTL(MSG_ARG_MTONCE),
1059                                             MSG_ORIG(MSG_ARG_D));
1060                                 else
1061                                         dflag = SET_FALSE;
1062                         } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1063                                 if (dflag != SET_UNKNOWN)
1064                                         ld_eprintf(ofl, ERR_WARNING_NF,
1065                                             MSG_INTL(MSG_ARG_MTONCE),
1066                                             MSG_ORIG(MSG_ARG_D));
1067                                 else
1068                                         dflag = SET_TRUE;
1069                         } else {
1070                                 ld_eprintf(ofl, ERR_FATAL,
1071                                     MSG_INTL(MSG_ARG_ILLEGAL),
1072                                     MSG_ORIG(MSG_ARG_D), optarg);
1073                         }
1074                         break;
1075 
1076                 case 'e':
1077                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1078                         if (ofl->ofl_entry)
1079                                 ld_eprintf(ofl, ERR_WARNING_NF,
1080                                     MSG_INTL(MSG_MARG_MTONCE),
1081                                     MSG_INTL(MSG_MARG_ENTRY));
1082                         else
1083                                 ofl->ofl_entry = (void *)optarg;
1084                         break;
1085 
1086                 case 'f':
1087                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1088                         if (ofl->ofl_filtees &&
1089                             (!(ofl->ofl_flags & FLG_OF_AUX))) {
1090                                 ld_eprintf(ofl, ERR_FATAL,
1091                                     MSG_INTL(MSG_MARG_INCOMP),
1092                                     MSG_INTL(MSG_MARG_FILTER_AUX),
1093                                     MSG_INTL(MSG_MARG_FILTER));
1094                         } else {
1095                                 if ((ofl->ofl_filtees =
1096                                     add_string(ofl->ofl_filtees, optarg)) ==
1097                                     (const char *)S_ERROR)
1098                                         return (S_ERROR);
1099                                 ofl->ofl_flags |= FLG_OF_AUX;
1100                         }
1101                         break;
1102 
1103                 case 'F':
1104                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1105                         if (ofl->ofl_filtees &&
1106                             (ofl->ofl_flags & FLG_OF_AUX)) {
1107                                 ld_eprintf(ofl, ERR_FATAL,
1108                                     MSG_INTL(MSG_MARG_INCOMP),
1109                                     MSG_INTL(MSG_MARG_FILTER),
1110                                     MSG_INTL(MSG_MARG_FILTER_AUX));
1111                         } else {
1112                                 if ((ofl->ofl_filtees =
1113                                     add_string(ofl->ofl_filtees, optarg)) ==
1114                                     (const char *)S_ERROR)
1115                                         return (S_ERROR);
1116                         }
1117                         break;
1118 
1119                 case 'h':
1120                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1121                         if (ofl->ofl_soname)
1122                                 ld_eprintf(ofl, ERR_WARNING_NF,
1123                                     MSG_INTL(MSG_MARG_MTONCE),
1124                                     MSG_INTL(MSG_MARG_SONAME));
1125                         else
1126                                 ofl->ofl_soname = (const char *)optarg;
1127                         break;
1128 
1129                 case 'i':
1130                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1131                         ofl->ofl_flags |= FLG_OF_IGNENV;
1132                         break;
1133 
1134                 case 'I':
1135                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1136                         if (ofl->ofl_interp)
1137                                 ld_eprintf(ofl, ERR_WARNING_NF,
1138                                     MSG_INTL(MSG_ARG_MTONCE),
1139                                     MSG_ORIG(MSG_ARG_CI));
1140                         else
1141                                 ofl->ofl_interp = (const char *)optarg;
1142                         break;
1143 
1144                 case 'l':
1145                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1146                         /*
1147                          * For now, count any library as a shared object.  This
1148                          * is used to size the internal symbol cache.  This
1149                          * value is recalculated later on actual file processing
1150                          * to get an accurate shared object count.
1151                          */
1152                         ofl->ofl_soscnt++;
1153                         break;
1154 
1155                 case 'm':
1156                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1157                         ofl->ofl_flags |= FLG_OF_GENMAP;
1158                         break;
1159 
1160                 case 'o':
1161                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1162                         if (ofl->ofl_name)
1163                                 ld_eprintf(ofl, ERR_WARNING_NF,
1164                                     MSG_INTL(MSG_MARG_MTONCE),
1165                                     MSG_INTL(MSG_MARG_OUTFILE));
1166                         else
1167                                 ofl->ofl_name = (const char *)optarg;
1168                         break;
1169 
1170                 case 'p':
1171                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1172 
1173                         /*
1174                          * Multiple instances of this option may occur.  Each
1175                          * additional instance is effectively concatenated to
1176                          * the previous separated by a colon.
1177                          */
1178                         if (*optarg != '\0') {
1179                                 if ((ofl->ofl_audit =
1180                                     add_string(ofl->ofl_audit,
1181                                     optarg)) == (const char *)S_ERROR)
1182                                         return (S_ERROR);
1183                         }
1184                         break;
1185 
1186                 case 'P':
1187                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1188 
1189                         /*
1190                          * Multiple instances of this option may occur.  Each
1191                          * additional instance is effectively concatenated to
1192                          * the previous separated by a colon.
1193                          */
1194                         if (*optarg != '\0') {
1195                                 if ((ofl->ofl_depaudit =
1196                                     add_string(ofl->ofl_depaudit,
1197                                     optarg)) == (const char *)S_ERROR)
1198                                         return (S_ERROR);
1199                         }
1200                         break;
1201 
1202                 case 'r':
1203                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1204                         rflag = TRUE;
1205                         break;
1206 
1207                 case 'R':
1208                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1209 
1210                         /*
1211                          * Multiple instances of this option may occur.  Each
1212                          * additional instance is effectively concatenated to
1213                          * the previous separated by a colon.
1214                          */
1215                         if (*optarg != '\0') {
1216                                 if ((ofl->ofl_rpath =
1217                                     add_string(ofl->ofl_rpath,
1218                                     optarg)) == (const char *)S_ERROR)
1219                                         return (S_ERROR);
1220                         }
1221                         break;
1222 
1223                 case 's':
1224                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1225                         sflag = TRUE;
1226                         break;
1227 
1228                 case 't':
1229                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1230                         ofl->ofl_flags |= FLG_OF_NOWARN;
1231                         break;
1232 
1233                 case 'u':
1234                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1235                         break;
1236 
1237                 case 'z':
1238                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1239 
1240                         /*
1241                          * Skip comma that might be present between -z and its
1242                          * argument (e.g. if -Wl,-z,assert-deflib was passed).
1243                          */
1244                         if (strncmp(optarg, MSG_ORIG(MSG_STR_COMMA),
1245                              MSG_STR_COMMA_SIZE) == 0)
1246                                 optarg++;
1247 
1248                         /*
1249                          * For specific help, print our usage message and exit
1250                          * immediately to ensure a 0 return code.
1251                          */
1252                         if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
1253                             MSG_ARG_HELP_SIZE) == 0) {
1254                                 usage_mesg(TRUE);
1255                                 exit(0);
1256                         }
1257 
1258                         /*
1259                          * For some options set a flag - further consistancy
1260                          * checks will be carried out in check_flags().
1261                          */
1262                         if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1263                             MSG_ARG_LD32_SIZE) == 0) ||
1264                             (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1265                             MSG_ARG_LD64_SIZE) == 0)) {
1266                                 if (createargv(ofl, usage) == S_ERROR)
1267                                         return (S_ERROR);
1268 
1269                         } else if (
1270                             strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
1271                                 if (zdflag != SET_UNKNOWN)
1272                                         ld_eprintf(ofl, ERR_WARNING_NF,
1273                                             MSG_INTL(MSG_ARG_MTONCE),
1274                                             MSG_ORIG(MSG_ARG_ZDEFNODEF));
1275                                 else
1276                                         zdflag = SET_TRUE;
1277                                 ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1278                         } else if (strcmp(optarg,
1279                             MSG_ORIG(MSG_ARG_NODEFS)) == 0) {
1280                                 if (zdflag != SET_UNKNOWN)
1281                                         ld_eprintf(ofl, ERR_WARNING_NF,
1282                                             MSG_INTL(MSG_ARG_MTONCE),
1283                                             MSG_ORIG(MSG_ARG_ZDEFNODEF));
1284                                 else
1285                                         zdflag = SET_FALSE;
1286                                 ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1287                         } else if (strcmp(optarg,
1288                             MSG_ORIG(MSG_ARG_TEXT)) == 0) {
1289                                 if (ztflag &&
1290                                     (ztflag != MSG_ORIG(MSG_ARG_ZTEXT)))
1291                                         ld_eprintf(ofl, ERR_FATAL,
1292                                             MSG_INTL(MSG_ARG_INCOMP),
1293                                             MSG_ORIG(MSG_ARG_ZTEXT),
1294                                             ztflag);
1295                                 ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
1296                         } else if (strcmp(optarg,
1297                             MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
1298                                 if (ztflag &&
1299                                     (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF)))
1300                                         ld_eprintf(ofl, ERR_FATAL,
1301                                             MSG_INTL(MSG_ARG_INCOMP),
1302                                             MSG_ORIG(MSG_ARG_ZTEXTOFF),
1303                                             ztflag);
1304                                 ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
1305                         } else if (strcmp(optarg,
1306                             MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
1307                                 if (ztflag &&
1308                                     (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN)))
1309                                         ld_eprintf(ofl, ERR_FATAL,
1310                                             MSG_INTL(MSG_ARG_INCOMP),
1311                                             MSG_ORIG(MSG_ARG_ZTEXTWARN),
1312                                             ztflag);
1313                                 ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
1314 
1315                         /*
1316                          * For other options simply set the ofl flags directly.
1317                          */
1318                         } else if (strcmp(optarg,
1319                             MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
1320                                 ofl->ofl_flags1 |= FLG_OF1_RESCAN;
1321                         } else if (strcmp(optarg,
1322                             MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
1323                                 ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
1324                         } else if (strcmp(optarg,
1325                             MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
1326                                 zlflag = TRUE;
1327                         } else if (strcmp(optarg,
1328                             MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
1329                                 ofl->ofl_dtflags_1 |= DF_1_NORELOC;
1330                         } else if (strcmp(optarg,
1331                             MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
1332                                 ofl->ofl_flags |= FLG_OF_NOVERSEC;
1333                         } else if (strcmp(optarg,
1334                             MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
1335                                 ofl->ofl_flags |= FLG_OF_MULDEFS;
1336                         } else if (strcmp(optarg,
1337                             MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
1338                                 ofl->ofl_flags |= FLG_OF_REDLSYM;
1339                         } else if (strcmp(optarg,
1340                             MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
1341                                 ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
1342                         } else if (strcmp(optarg,
1343                             MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
1344                                 ofl->ofl_dtflags_1 |= DF_1_NODELETE;
1345                         } else if (strcmp(optarg,
1346                             MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
1347                                 ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
1348                         } else if (strcmp(optarg,
1349                             MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
1350                                 ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
1351                         } else if (strcmp(optarg,
1352                             MSG_ORIG(MSG_ARG_NOW)) == 0) {
1353                                 ofl->ofl_dtflags_1 |= DF_1_NOW;
1354                                 ofl->ofl_dtflags |= DF_BIND_NOW;
1355                         } else if (strcmp(optarg,
1356                             MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
1357                                 ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
1358                                 ofl->ofl_dtflags |= DF_ORIGIN;
1359                         } else if (strcmp(optarg,
1360                             MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1361                                 ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1362                         } else if (strcmp(optarg,
1363                             MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1364                                 ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1365                         } else if (strcmp(optarg,
1366                             MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1367                                 ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1368                         } else if (strcmp(optarg,
1369                             MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1370                                 ofl->ofl_flags |= FLG_OF_VERBOSE;
1371                         } else if (strcmp(optarg,
1372                             MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1373                                 ofl->ofl_flags |= FLG_OF_COMREL;
1374                         } else if (strcmp(optarg,
1375                             MSG_ORIG(MSG_ARG_NOCOMBRELOC)) == 0) {
1376                                 ofl->ofl_flags |= FLG_OF_NOCOMREL;
1377                         } else if (strcmp(optarg,
1378                             MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1379                                 ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1380                         } else if (strcmp(optarg,
1381                             MSG_ORIG(MSG_ARG_NOINTERP)) == 0) {
1382                                 ofl->ofl_flags1 |= FLG_OF1_NOINTRP;
1383                         } else if (strcmp(optarg,
1384                             MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1385                                 zinflag = TRUE;
1386                         } else if (strcmp(optarg,
1387                             MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1388                                 ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1389                         } else if (strcmp(optarg,
1390                             MSG_ORIG(MSG_ARG_RELAXRELOC)) == 0) {
1391                                 ofl->ofl_flags1 |= FLG_OF1_RLXREL;
1392                         } else if (strcmp(optarg,
1393                             MSG_ORIG(MSG_ARG_NORELAXRELOC)) == 0) {
1394                                 ofl->ofl_flags1 |= FLG_OF1_NRLXREL;
1395                         } else if (strcmp(optarg,
1396                             MSG_ORIG(MSG_ARG_NOLDYNSYM)) == 0) {
1397                                 ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1398                         } else if (strcmp(optarg,
1399                             MSG_ORIG(MSG_ARG_GLOBAUDIT)) == 0) {
1400                                 ofl->ofl_dtflags_1 |= DF_1_GLOBAUDIT;
1401                         } else if (strcmp(optarg,
1402                             MSG_ORIG(MSG_ARG_NOSIGHANDLER)) == 0) {
1403                                 ofl->ofl_flags1 |= FLG_OF1_NOSGHND;
1404                         } else if (strcmp(optarg,
1405                             MSG_ORIG(MSG_ARG_SYMBOLCAP)) == 0) {
1406                                 ofl->ofl_flags |= FLG_OF_OTOSCAP;
1407 
1408                         /*
1409                          * Check archive group usage
1410                          *      -z rescan-start ... -z rescan-end
1411                          * to ensure they don't overlap and are well formed.
1412                          */
1413                         } else if (strcmp(optarg,
1414                             MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1415                                 if (ofl->ofl_ars_gsandx == 0) {
1416                                         ofl->ofl_ars_gsandx = ndx;
1417                                 } else if (ofl->ofl_ars_gsandx > 0) {
1418                                         /* Another group is still open */
1419                                         ld_eprintf(ofl, ERR_FATAL,
1420                                             MSG_INTL(MSG_ARG_AR_GRP_OLAP),
1421                                             MSG_INTL(MSG_MARG_AR_GRPS));
1422                                         /* Don't report cascading errors */
1423                                         ofl->ofl_ars_gsandx = -1;
1424                                 }
1425                         } else if (strcmp(optarg,
1426                             MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1427                                 if (ofl->ofl_ars_gsandx > 0) {
1428                                         ofl->ofl_ars_gsandx = 0;
1429                                 } else if (ofl->ofl_ars_gsandx == 0) {
1430                                         /* There was no matching begin */
1431                                         ld_eprintf(ofl, ERR_FATAL,
1432                                             MSG_INTL(MSG_ARG_AR_GRP_BAD),
1433                                             MSG_INTL(MSG_MARG_AR_GRP_END),
1434                                             MSG_INTL(MSG_MARG_AR_GRP_START));
1435                                         /* Don't report cascading errors */
1436                                         ofl->ofl_ars_gsandx = -1;
1437                                 }
1438 
1439                         /*
1440                          * If -z wrap is seen, enter the symbol to be wrapped
1441                          * into the wrap AVL tree.
1442                          */
1443                         } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_WRAP),
1444                             MSG_ARG_WRAP_SIZE) == 0) {
1445                                 if (ld_wrap_enter(ofl,
1446                                     optarg + MSG_ARG_WRAP_SIZE) == NULL)
1447                                         return (S_ERROR);
1448                         } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASLR),
1449                             MSG_ARG_ASLR_SIZE) == 0) {
1450                                 char *p = optarg + MSG_ARG_ASLR_SIZE;
1451                                 if (*p == '\0') {
1452                                         ofl->ofl_aslr = 1;
1453                                 } else if (*p == '=') {
1454                                         p++;
1455 
1456                                         if ((strcmp(p,
1457                                             MSG_ORIG(MSG_ARG_ENABLED)) == 0) ||
1458                                             (strcmp(p,
1459                                             MSG_ORIG(MSG_ARG_ENABLE)) == 0)) {
1460                                                 ofl->ofl_aslr = 1;
1461                                         } else if ((strcmp(p,
1462                                             MSG_ORIG(MSG_ARG_DISABLED)) == 0) ||
1463                                             (strcmp(p,
1464                                             MSG_ORIG(MSG_ARG_DISABLE)) == 0)) {
1465                                                 ofl->ofl_aslr = -1;
1466                                         } else {
1467                                                 ld_eprintf(ofl, ERR_FATAL,
1468                                                     MSG_INTL(MSG_ARG_ILLEGAL),
1469                                                     MSG_ORIG(MSG_ARG_ZASLR), p);
1470                                                 return (S_ERROR);
1471                                         }
1472                                 } else {
1473                                         ld_eprintf(ofl, ERR_FATAL,
1474                                             MSG_INTL(MSG_ARG_ILLEGAL),
1475                                             MSG_ORIG(MSG_ARG_Z), optarg);
1476                                         return (S_ERROR);
1477                                 }
1478                         } else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
1479                             MSG_ARG_GUIDE_SIZE) == 0) &&
1480                             ((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
1481                             (optarg[MSG_ARG_GUIDE_SIZE] == '\0'))) {
1482                                 if (!guidance_parse(ofl, optarg))
1483                                         return (S_ERROR);
1484                         } else if (strcmp(optarg,
1485                             MSG_ORIG(MSG_ARG_FATWARN)) == 0) {
1486                                 if (zfwflag  == SET_FALSE) {
1487                                         ld_eprintf(ofl, ERR_WARNING_NF,
1488                                             MSG_INTL(MSG_ARG_MTONCE),
1489                                             MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1490                                 } else {
1491                                         zfwflag = SET_TRUE;
1492                                         ofl->ofl_flags |= FLG_OF_FATWARN;
1493                                 }
1494                         } else if (strcmp(optarg,
1495                             MSG_ORIG(MSG_ARG_NOFATWARN)) == 0) {
1496                                 if (zfwflag  == SET_TRUE)
1497                                         ld_eprintf(ofl, ERR_WARNING_NF,
1498                                             MSG_INTL(MSG_ARG_MTONCE),
1499                                             MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1500                                 else
1501                                         zfwflag = SET_FALSE;
1502 
1503                         /*
1504                          * Process everything related to -z assert-deflib. This
1505                          * must be done in pass 1 because it gets used in pass
1506                          * 2.
1507                          */
1508                         } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASSDEFLIB),
1509                             MSG_ARG_ASSDEFLIB_SIZE) == 0) {
1510                                 if (assdeflib_parse(ofl, optarg) != TRUE)
1511                                         return (S_ERROR);
1512                         /*
1513                          * The following options just need validation as they
1514                          * are interpreted on the second pass through the
1515                          * command line arguments.
1516                          */
1517                         } else if (
1518                             strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1519                             MSG_ARG_INITARRAY_SIZE) &&
1520                             strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1521                             MSG_ARG_FINIARRAY_SIZE) &&
1522                             strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1523                             MSG_ARG_PREINITARRAY_SIZE) &&
1524                             strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1525                             MSG_ARG_RTLDINFO_SIZE) &&
1526                             strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1527                             MSG_ARG_DTRACE_SIZE) &&
1528                             strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1529                             strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1530                             strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1531                             strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1532                             strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1533                             strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1534                             strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1535                             strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1536                             strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
1537                             strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1538                             strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
1539                             strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
1540                             strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
1541                             MSG_ARG_TARGET_SIZE) &&
1542                             strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
1543                             strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
1544                                 ld_eprintf(ofl, ERR_FATAL,
1545                                     MSG_INTL(MSG_ARG_ILLEGAL),
1546                                     MSG_ORIG(MSG_ARG_Z), optarg);
1547                         }
1548 
1549                         break;
1550 
1551                 case 'D':
1552                         /*
1553                          * If we have not yet read any input files go ahead
1554                          * and process any debugging options (this allows any
1555                          * argument processing, entrance criteria and library
1556                          * initialization to be displayed).  Otherwise, if an
1557                          * input file has been seen, skip interpretation until
1558                          * process_files (this allows debugging to be turned
1559                          * on and off around individual groups of files).
1560                          */
1561                         Dflag = 1;
1562                         if (ofl->ofl_objscnt == 0) {
1563                                 if (dbg_setup(ofl, optarg, 2) == 0)
1564                                         return (S_ERROR);
1565                         }
1566 
1567                         /*
1568                          * A diagnostic can only be provided after dbg_setup().
1569                          * As this is the first diagnostic that can be produced
1570                          * by ld(1), issue a title for timing and basic output.
1571                          */
1572                         if ((optitle == 0) && DBG_ENABLED) {
1573                                 optitle++;
1574                                 DBG_CALL(Dbg_basic_options(ofl->ofl_lml));
1575                         }
1576                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1577                         break;
1578 
1579                 case 'B':
1580                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1581                         if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1582                                 if (Bdflag == SET_FALSE) {
1583                                         ld_eprintf(ofl, ERR_FATAL,
1584                                             MSG_INTL(MSG_ARG_INCOMP),
1585                                             MSG_ORIG(MSG_ARG_BNODIRECT),
1586                                             MSG_ORIG(MSG_ARG_BDIRECT));
1587                                 } else {
1588                                         Bdflag = SET_TRUE;
1589                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1590                                 }
1591                         } else if (strcmp(optarg,
1592                             MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1593                                 if (Bdflag == SET_TRUE) {
1594                                         ld_eprintf(ofl, ERR_FATAL,
1595                                             MSG_INTL(MSG_ARG_INCOMP),
1596                                             MSG_ORIG(MSG_ARG_BDIRECT),
1597                                             MSG_ORIG(MSG_ARG_BNODIRECT));
1598                                 } else {
1599                                         Bdflag = SET_FALSE;
1600                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1601                                 }
1602                         } else if (strcmp(optarg,
1603                             MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1604                                 Bsflag = TRUE;
1605                         else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1606                                 ofl->ofl_flags |= FLG_OF_PROCRED;
1607                         else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1608                                 Blflag = TRUE;
1609                         else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1610                                 Bgflag = TRUE;
1611                         else if (strcmp(optarg,
1612                             MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1613                                 Beflag = TRUE;
1614                         else if (strcmp(optarg,
1615                             MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
1616                                 ld_eprintf(ofl, ERR_WARNING,
1617                                     MSG_INTL(MSG_ARG_UNSUPPORTED),
1618                                     MSG_ORIG(MSG_ARG_BTRANSLATOR));
1619                         } else if (strcmp(optarg,
1620                             MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1621                             strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1622                                 ld_eprintf(ofl, ERR_FATAL,
1623                                     MSG_INTL(MSG_ARG_ILLEGAL),
1624                                     MSG_ORIG(MSG_ARG_CB), optarg);
1625                         }
1626                         break;
1627 
1628                 case 'G':
1629                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1630                         Gflag = TRUE;
1631                         break;
1632 
1633                 case 'L':
1634                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1635                         break;
1636 
1637                 case 'M':
1638                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1639                         if (aplist_append(&(ofl->ofl_maps), optarg,
1640                             AL_CNT_OFL_MAPFILES) == NULL)
1641                                 return (S_ERROR);
1642                         break;
1643 
1644                 case 'N':
1645                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1646                         break;
1647 
1648                 case 'Q':
1649                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1650                         if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1651                                 if (Qflag != SET_UNKNOWN)
1652                                         ld_eprintf(ofl, ERR_WARNING_NF,
1653                                             MSG_INTL(MSG_ARG_MTONCE),
1654                                             MSG_ORIG(MSG_ARG_CQ));
1655                                 else
1656                                         Qflag = SET_FALSE;
1657                         } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1658                                 if (Qflag != SET_UNKNOWN)
1659                                         ld_eprintf(ofl, ERR_WARNING_NF,
1660                                             MSG_INTL(MSG_ARG_MTONCE),
1661                                             MSG_ORIG(MSG_ARG_CQ));
1662                                 else
1663                                         Qflag = SET_TRUE;
1664                         } else {
1665                                 ld_eprintf(ofl, ERR_FATAL,
1666                                     MSG_INTL(MSG_ARG_ILLEGAL),
1667                                     MSG_ORIG(MSG_ARG_CQ), optarg);
1668                         }
1669                         break;
1670 
1671                 case 'S':
1672                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1673                         if (aplist_append(&lib_support, optarg,
1674                             AL_CNT_SUPPORT) == NULL)
1675                                 return (S_ERROR);
1676                         break;
1677 
1678                 case 'V':
1679                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1680                         if (!Vflag)
1681                                 (void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1682                                     ofl->ofl_sgsid);
1683                         Vflag = TRUE;
1684                         break;
1685 
1686                 case 'Y':
1687                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1688                         if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1689                                 if (Llibdir)
1690                                         ld_eprintf(ofl, ERR_WARNING_NF,
1691                                             MSG_INTL(MSG_ARG_MTONCE),
1692                                             MSG_ORIG(MSG_ARG_CYL));
1693                                 else
1694                                         Llibdir = optarg + 2;
1695                         } else if (strncmp(optarg,
1696                             MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1697                                 if (Ulibdir)
1698                                         ld_eprintf(ofl, ERR_WARNING_NF,
1699                                             MSG_INTL(MSG_ARG_MTONCE),
1700                                             MSG_ORIG(MSG_ARG_CYU));
1701                                 else
1702                                         Ulibdir = optarg + 2;
1703                         } else if (strncmp(optarg,
1704                             MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1705                                 if (Plibpath)
1706                                         ld_eprintf(ofl, ERR_WARNING_NF,
1707                                             MSG_INTL(MSG_ARG_MTONCE),
1708                                             MSG_ORIG(MSG_ARG_CYP));
1709                                 else
1710                                         Plibpath = optarg + 2;
1711                         } else {
1712                                 ld_eprintf(ofl, ERR_FATAL,
1713                                     MSG_INTL(MSG_ARG_ILLEGAL),
1714                                     MSG_ORIG(MSG_ARG_CY), optarg);
1715                         }
1716                         break;
1717 
1718                 case '?':
1719                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1720                         /*
1721                          * If the option character is '-', we're looking at a
1722                          * long option which couldn't be translated, display a
1723                          * more useful error.
1724                          */
1725                         if (optopt == '-') {
1726                                 eprintf(ofl->ofl_lml, ERR_FATAL,
1727                                     MSG_INTL(MSG_ARG_LONG_UNKNOWN),
1728                                     argv[optind-1]);
1729                         } else {
1730                                 eprintf(ofl->ofl_lml, ERR_FATAL,
1731                                     MSG_INTL(MSG_ARG_UNKNOWN), optopt);
1732                         }
1733                         (*usage)++;
1734                         break;
1735 
1736                 default:
1737                         break;
1738                 }
1739 
1740                 /*
1741                  * Update the argument index for the next getopt() iteration.
1742                  */
1743                 ndx = optind;
1744         }
1745         return (1);
1746 }
1747 
1748 /*
1749  * Parsing options pass2 for
1750  */
1751 static uintptr_t
1752 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1753 {
1754         int     c, ndx = optind;
1755 
1756         while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1757                 Ifl_desc        *ifl;
1758                 Sym_desc        *sdp;
1759 
1760                 switch (c) {
1761                         case 'l':
1762                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1763                                     optarg));
1764                                 if (ld_find_library(optarg, ofl) == S_ERROR)
1765                                         return (S_ERROR);
1766                                 break;
1767                         case 'B':
1768                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1769                                     optarg));
1770                                 if (strcmp(optarg,
1771                                     MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1772                                         if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1773                                                 ofl->ofl_flags |=
1774                                                     FLG_OF_DYNLIBS;
1775                                         else {
1776                                                 ld_eprintf(ofl, ERR_FATAL,
1777                                                     MSG_INTL(MSG_ARG_ST_INCOMP),
1778                                                     MSG_ORIG(MSG_ARG_BDYNAMIC));
1779                                         }
1780                                 } else if (strcmp(optarg,
1781                                     MSG_ORIG(MSG_ARG_STATIC)) == 0)
1782                                         ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1783                                 break;
1784                         case 'L':
1785                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1786                                     optarg));
1787                                 if (ld_add_libdir(ofl, optarg) == S_ERROR)
1788                                         return (S_ERROR);
1789                                 break;
1790                         case 'N':
1791                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1792                                     optarg));
1793                                 /*
1794                                  * Record DT_NEEDED string
1795                                  */
1796                                 if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
1797                                         ld_eprintf(ofl, ERR_FATAL,
1798                                             MSG_INTL(MSG_ARG_ST_INCOMP),
1799                                             MSG_ORIG(MSG_ARG_CN));
1800                                 if (((ifl = libld_calloc(1,
1801                                     sizeof (Ifl_desc))) == NULL) ||
1802                                     (aplist_append(&ofl->ofl_sos, ifl,
1803                                     AL_CNT_OFL_LIBS) == NULL))
1804                                         return (S_ERROR);
1805 
1806                                 ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1807                                 ifl->ifl_soname = optarg;
1808                                 ifl->ifl_flags = (FLG_IF_NEEDSTR |
1809                                     FLG_IF_FILEREF | FLG_IF_DEPREQD);
1810 
1811                                 break;
1812                         case 'D':
1813                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1814                                     optarg));
1815                                 (void) dbg_setup(ofl, optarg, 3);
1816                                 break;
1817                         case 'u':
1818                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1819                                     optarg));
1820                                 if (ld_sym_add_u(optarg, ofl,
1821                                     MSG_STR_COMMAND) == (Sym_desc *)S_ERROR)
1822                                         return (S_ERROR);
1823                                 break;
1824                         case 'z':
1825                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1826                                     optarg));
1827                                 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1828                                     MSG_ARG_LD32_SIZE) == 0) ||
1829                                     (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1830                                     MSG_ARG_LD64_SIZE) == 0)) {
1831                                         if (createargv(ofl, 0) == S_ERROR)
1832                                                 return (S_ERROR);
1833                                 } else if (strcmp(optarg,
1834                                     MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1835                                         ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1836                                         ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1837                                 } else if (strcmp(optarg,
1838                                     MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1839                                         ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1840                                         ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1841                                 } else if (strcmp(optarg,
1842                                     MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1843                                         ofl->ofl_flags1 &=
1844                                             ~(FLG_OF1_ALLEXRT |
1845                                             FLG_OF1_WEAKEXT);
1846                                 } else if (strcmp(optarg,
1847                                     MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1848                                         ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1849                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1850                                 } else if (strcmp(optarg,
1851                                     MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1852                                         ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1853                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1854                                 } else if (strcmp(optarg,
1855                                     MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1856                                         ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1857                                 } else if (strcmp(optarg,
1858                                     MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1859                                         ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1860                                 } else if (strcmp(optarg,
1861                                     MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1862                                         ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1863                                         ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1864                                 } else if (strcmp(optarg,
1865                                     MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1866                                         ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1867                                         ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1868                                 } else if (strcmp(optarg,
1869                                     MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1870                                         ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1871                                 } else if (strcmp(optarg,
1872                                     MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1873                                         ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1874                                 } else if (strncmp(optarg,
1875                                     MSG_ORIG(MSG_ARG_INITARRAY),
1876                                     MSG_ARG_INITARRAY_SIZE) == 0) {
1877                                         if (((sdp = ld_sym_add_u(optarg +
1878                                             MSG_ARG_INITARRAY_SIZE, ofl,
1879                                             MSG_STR_COMMAND)) ==
1880                                             (Sym_desc *)S_ERROR) ||
1881                                             (aplist_append(&ofl->ofl_initarray,
1882                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1883                                                 return (S_ERROR);
1884                                 } else if (strncmp(optarg,
1885                                     MSG_ORIG(MSG_ARG_FINIARRAY),
1886                                     MSG_ARG_FINIARRAY_SIZE) == 0) {
1887                                         if (((sdp = ld_sym_add_u(optarg +
1888                                             MSG_ARG_FINIARRAY_SIZE, ofl,
1889                                             MSG_STR_COMMAND)) ==
1890                                             (Sym_desc *)S_ERROR) ||
1891                                             (aplist_append(&ofl->ofl_finiarray,
1892                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1893                                                 return (S_ERROR);
1894                                 } else if (strncmp(optarg,
1895                                     MSG_ORIG(MSG_ARG_PREINITARRAY),
1896                                     MSG_ARG_PREINITARRAY_SIZE) == 0) {
1897                                         if (((sdp = ld_sym_add_u(optarg +
1898                                             MSG_ARG_PREINITARRAY_SIZE, ofl,
1899                                             MSG_STR_COMMAND)) ==
1900                                             (Sym_desc *)S_ERROR) ||
1901                                             (aplist_append(&ofl->ofl_preiarray,
1902                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1903                                                 return (S_ERROR);
1904                                 } else if (strncmp(optarg,
1905                                     MSG_ORIG(MSG_ARG_RTLDINFO),
1906                                     MSG_ARG_RTLDINFO_SIZE) == 0) {
1907                                         if (((sdp = ld_sym_add_u(optarg +
1908                                             MSG_ARG_RTLDINFO_SIZE, ofl,
1909                                             MSG_STR_COMMAND)) ==
1910                                             (Sym_desc *)S_ERROR) ||
1911                                             (aplist_append(&ofl->ofl_rtldinfo,
1912                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1913                                                 return (S_ERROR);
1914                                 } else if (strncmp(optarg,
1915                                     MSG_ORIG(MSG_ARG_DTRACE),
1916                                     MSG_ARG_DTRACE_SIZE) == 0) {
1917                                         if ((sdp = ld_sym_add_u(optarg +
1918                                             MSG_ARG_DTRACE_SIZE, ofl,
1919                                             MSG_STR_COMMAND)) ==
1920                                             (Sym_desc *)S_ERROR)
1921                                                 return (S_ERROR);
1922                                         ofl->ofl_dtracesym = sdp;
1923                                 } else if (strcmp(optarg,
1924                                     MSG_ORIG(MSG_ARG_RESCAN_NOW)) == 0) {
1925                                         if (ld_rescan_archives(ofl, 0, ndx) ==
1926                                             S_ERROR)
1927                                                 return (S_ERROR);
1928                                 } else if (strcmp(optarg,
1929                                     MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1930                                         ofl->ofl_ars_gsndx = ofl->ofl_arscnt;
1931                                         ofl->ofl_ars_gsandx = ndx;
1932                                 } else if (strcmp(optarg,
1933                                     MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1934                                         if (ld_rescan_archives(ofl, 1, ndx) ==
1935                                             S_ERROR)
1936                                                 return (S_ERROR);
1937                                 } else if (strcmp(optarg,
1938                                     MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
1939                                         ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
1940                                 } else if (strcmp(optarg,
1941                                     MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
1942                                         ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
1943                                 }
1944                         default:
1945                                 break;
1946                 }
1947 
1948                 /*
1949                  * Update the argument index for the next getopt() iteration.
1950                  */
1951                 ndx = optind;
1952         }
1953         return (1);
1954 }
1955 
1956 /*
1957  *
1958  * Pass 1 -- process_flags: collects all options and sets flags
1959  */
1960 static uintptr_t
1961 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
1962 {
1963         for (; optind < argc; optind++) {
1964                 /*
1965                  * If we detect some more options return to getopt().
1966                  * Checking argv[optind][1] against null prevents a forever
1967                  * loop if an unadorned `-' argument is passed to us.
1968                  */
1969                 while ((optind < argc) && (argv[optind][0] == '-')) {
1970                         if (argv[optind][1] != '\0') {
1971                                 if (parseopt_pass1(ofl, argc, argv,
1972                                     usage) == S_ERROR)
1973                                         return (S_ERROR);
1974                         } else if (++optind < argc)
1975                                 continue;
1976                 }
1977                 if (optind >= argc)
1978                         break;
1979                 ofl->ofl_objscnt++;
1980         }
1981 
1982         /* Did an unterminated archive group run off the end? */
1983         if (ofl->ofl_ars_gsandx > 0) {
1984                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
1985                     MSG_INTL(MSG_MARG_AR_GRP_START),
1986                     MSG_INTL(MSG_MARG_AR_GRP_END));
1987                 return (S_ERROR);
1988         }
1989 
1990         return (1);
1991 }
1992 
1993 uintptr_t
1994 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
1995 {
1996         int     usage = 0;      /* Collect all argument errors before exit */
1997 
1998         if (argc < 2) {
1999                 usage_mesg(FALSE);
2000                 return (S_ERROR);
2001         }
2002 
2003         /*
2004          * Option handling
2005          */
2006         opterr = 0;
2007         optind = 1;
2008         if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
2009                 return (S_ERROR);
2010 
2011         /*
2012          * Having parsed everything, did we have any usage errors.
2013          */
2014         if (usage) {
2015                 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
2016                 return (S_ERROR);
2017         }
2018 
2019         return (check_flags(ofl, argc));
2020 }
2021 
2022 /*
2023  * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
2024  * files.
2025  */
2026 static uintptr_t
2027 process_files_com(Ofl_desc *ofl, int argc, char **argv)
2028 {
2029         for (; optind < argc; optind++) {
2030                 int             fd;
2031                 uintptr_t       open_ret;
2032                 char            *path;
2033                 Rej_desc        rej = { 0 };
2034 
2035                 /*
2036                  * If we detect some more options return to getopt().
2037                  * Checking argv[optind][1] against null prevents a forever
2038                  * loop if an unadorned `-' argument is passed to us.
2039                  */
2040                 while ((optind < argc) && (argv[optind][0] == '-')) {
2041                         if (argv[optind][1] != '\0') {
2042                                 if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
2043                                         return (S_ERROR);
2044                         } else if (++optind < argc)
2045                                 continue;
2046                 }
2047                 if (optind >= argc)
2048                         break;
2049 
2050                 path = argv[optind];
2051                 if ((fd = open(path, O_RDONLY)) == -1) {
2052                         int err = errno;
2053 
2054                         ld_eprintf(ofl, ERR_FATAL,
2055                             MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
2056                         continue;
2057                 }
2058 
2059                 DBG_CALL(Dbg_args_file(ofl->ofl_lml, optind, path));
2060 
2061                 open_ret = ld_process_open(path, path, &fd, ofl,
2062                     (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej, NULL);
2063                 if (fd != -1)
2064                         (void) close(fd);
2065                 if (open_ret == S_ERROR)
2066                         return (S_ERROR);
2067 
2068                 /*
2069                  * Check for mismatched input.
2070                  */
2071                 if (rej.rej_type) {
2072                         Conv_reject_desc_buf_t rej_buf;
2073 
2074                         ld_eprintf(ofl, ERR_FATAL,
2075                             MSG_INTL(reject[rej.rej_type]),
2076                             rej.rej_name ? rej.rej_name :
2077                             MSG_INTL(MSG_STR_UNKNOWN),
2078                             conv_reject_desc(&rej, &rej_buf,
2079                             ld_targ.t_m.m_mach));
2080                         return (1);
2081                 }
2082         }
2083         return (1);
2084 }
2085 
2086 uintptr_t
2087 ld_process_files(Ofl_desc *ofl, int argc, char **argv)
2088 {
2089         DBG_CALL(Dbg_basic_files(ofl->ofl_lml));
2090 
2091         /*
2092          * Process command line files (taking into account any applicable
2093          * preceding flags).  Return if any fatal errors have occurred.
2094          */
2095         opterr = 0;
2096         optind = 1;
2097         if (process_files_com(ofl, argc, argv) == S_ERROR)
2098                 return (S_ERROR);
2099         if (ofl->ofl_flags & FLG_OF_FATAL)
2100                 return (1);
2101 
2102         /*
2103          * Guidance: Use -B direct/nodirect or -z direct/nodirect.
2104          *
2105          * This is a backstop for the case where the link had no dependencies.
2106          * Otherwise, it will get caught by ld_process_ifl(). We need both,
2107          * because -z direct is positional, and its value at the time where
2108          * the first dependency is seen might be different than it is now.
2109          */
2110         if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
2111             OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
2112                 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
2113                 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
2114         }
2115 
2116         /*
2117          * Now that all command line files have been processed see if there are
2118          * any additional `needed' shared object dependencies.
2119          */
2120         if (ofl->ofl_soneed)
2121                 if (ld_finish_libs(ofl) == S_ERROR)
2122                         return (S_ERROR);
2123 
2124         /*
2125          * If rescanning archives is enabled, do so now to determine whether
2126          * there might still be members extracted to satisfy references from any
2127          * explicit objects.  Continue until no new objects are extracted.  Note
2128          * that this pass is carried out *after* processing any implicit objects
2129          * (above) as they may already have resolved any undefined references
2130          * from any explicit dependencies.
2131          */
2132         if (ofl->ofl_flags1 & FLG_OF1_RESCAN) {
2133                 if (ld_rescan_archives(ofl, 0, argc) == S_ERROR)
2134                         return (S_ERROR);
2135                 if (ofl->ofl_flags & FLG_OF_FATAL)
2136                         return (1);
2137         }
2138 
2139         /*
2140          * If debugging, provide statistics on each archives extraction, or flag
2141          * any archive that has provided no members.  Note that this could be a
2142          * nice place to free up much of the archive infrastructure, as we've
2143          * extracted any members we need.  However, as we presently don't free
2144          * anything under ld(1) there's not much point in proceeding further.
2145          */
2146         DBG_CALL(Dbg_statistics_ar(ofl));
2147 
2148         /*
2149          * If any version definitions have been established, either via input
2150          * from a mapfile or from the input relocatable objects, make sure any
2151          * version dependencies are satisfied, and version symbols created.
2152          */
2153         if (ofl->ofl_verdesc)
2154                 if (ld_vers_check_defs(ofl) == S_ERROR)
2155                         return (S_ERROR);
2156 
2157         /*
2158          * If input section ordering was specified within some segment
2159          * using a mapfile, verify that the expected sections were seen.
2160          */
2161         if (ofl->ofl_flags & FLG_OF_IS_ORDER)
2162                 ld_ent_check(ofl);
2163 
2164         return (1);
2165 }
2166 
2167 uintptr_t
2168 ld_init_strings(Ofl_desc *ofl)
2169 {
2170         uint_t  stflags;
2171 
2172         if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
2173                 stflags = 0;
2174         else
2175                 stflags = FLG_STNEW_COMPRESS;
2176 
2177         if (((ofl->ofl_shdrsttab = st_new(stflags)) == NULL) ||
2178             ((ofl->ofl_strtab = st_new(stflags)) == NULL) ||
2179             ((ofl->ofl_dynstrtab = st_new(stflags)) == NULL))
2180                 return (S_ERROR);
2181 
2182         return (0);
2183 }