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