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