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