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 
1552                         /*
1553                          * Process new-style output type specification, which
1554                          * we'll use in pass 2 and throughout.
1555                          */
1556                         } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_TYPE),
1557                             MSG_ARG_TYPE_SIZE) == 0) {
1558                                 char *p = optarg + MSG_ARG_TYPE_SIZE;
1559                                 if (*p != '=') {
1560                                         ld_eprintf(ofl, ERR_FATAL,
1561                                             MSG_INTL(MSG_ARG_ILLEGAL),
1562                                             MSG_ORIG(MSG_ARG_Z), optarg);
1563                                         return (S_ERROR);
1564                                 }
1565 
1566                                 p++;
1567                                 if (strcmp(p,
1568                                     MSG_ORIG(MSG_ARG_TYPE_RELOC)) == 0) {
1569                                         otype = OT_RELOC;
1570                                 } else if (strcmp(p,
1571                                     MSG_ORIG(MSG_ARG_TYPE_EXEC)) == 0) {
1572                                         otype = OT_EXEC;
1573                                 } else if (strcmp(p,
1574                                     MSG_ORIG(MSG_ARG_TYPE_SHARED)) == 0) {
1575                                         otype = OT_SHARED;
1576                                 } else if (strcmp(p,
1577                                     MSG_ORIG(MSG_ARG_TYPE_KMOD)) == 0) {
1578                                         otype = OT_KMOD;
1579                                 } else {
1580                                         ld_eprintf(ofl, ERR_FATAL,
1581                                             MSG_INTL(MSG_ARG_ILLEGAL),
1582                                             MSG_ORIG(MSG_ARG_Z), optarg);
1583                                         return (S_ERROR);
1584                                 }
1585                         /*
1586                          * The following options just need validation as they
1587                          * are interpreted on the second pass through the
1588                          * command line arguments.
1589                          */
1590                         } else if (
1591                             strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1592                             MSG_ARG_INITARRAY_SIZE) &&
1593                             strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1594                             MSG_ARG_FINIARRAY_SIZE) &&
1595                             strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1596                             MSG_ARG_PREINITARRAY_SIZE) &&
1597                             strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1598                             MSG_ARG_RTLDINFO_SIZE) &&
1599                             strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1600                             MSG_ARG_DTRACE_SIZE) &&
1601                             strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1602                             strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1603                             strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1604                             strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1605                             strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1606                             strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1607                             strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1608                             strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1609                             strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
1610                             strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1611                             strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
1612                             strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
1613                             strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
1614                             MSG_ARG_TARGET_SIZE) &&
1615                             strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
1616                             strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
1617                                 ld_eprintf(ofl, ERR_FATAL,
1618                                     MSG_INTL(MSG_ARG_ILLEGAL),
1619                                     MSG_ORIG(MSG_ARG_Z), optarg);
1620                         }
1621 
1622                         break;
1623 
1624                 case 'D':
1625                         /*
1626                          * If we have not yet read any input files go ahead
1627                          * and process any debugging options (this allows any
1628                          * argument processing, entrance criteria and library
1629                          * initialization to be displayed).  Otherwise, if an
1630                          * input file has been seen, skip interpretation until
1631                          * process_files (this allows debugging to be turned
1632                          * on and off around individual groups of files).
1633                          */
1634                         Dflag = 1;
1635                         if (ofl->ofl_objscnt == 0) {
1636                                 if (dbg_setup(ofl, optarg, 2) == 0)
1637                                         return (S_ERROR);
1638                         }
1639 
1640                         /*
1641                          * A diagnostic can only be provided after dbg_setup().
1642                          * As this is the first diagnostic that can be produced
1643                          * by ld(1), issue a title for timing and basic output.
1644                          */
1645                         if ((optitle == 0) && DBG_ENABLED) {
1646                                 optitle++;
1647                                 DBG_CALL(Dbg_basic_options(ofl->ofl_lml));
1648                         }
1649                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1650                         break;
1651 
1652                 case 'B':
1653                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1654                         if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1655                                 if (Bdflag == SET_FALSE) {
1656                                         ld_eprintf(ofl, ERR_FATAL,
1657                                             MSG_INTL(MSG_ARG_INCOMP),
1658                                             MSG_ORIG(MSG_ARG_BNODIRECT),
1659                                             MSG_ORIG(MSG_ARG_BDIRECT));
1660                                 } else {
1661                                         Bdflag = SET_TRUE;
1662                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1663                                 }
1664                         } else if (strcmp(optarg,
1665                             MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1666                                 if (Bdflag == SET_TRUE) {
1667                                         ld_eprintf(ofl, ERR_FATAL,
1668                                             MSG_INTL(MSG_ARG_INCOMP),
1669                                             MSG_ORIG(MSG_ARG_BDIRECT),
1670                                             MSG_ORIG(MSG_ARG_BNODIRECT));
1671                                 } else {
1672                                         Bdflag = SET_FALSE;
1673                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1674                                 }
1675                         } else if (strcmp(optarg,
1676                             MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1677                                 Bsflag = TRUE;
1678                         else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1679                                 ofl->ofl_flags |= FLG_OF_PROCRED;
1680                         else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1681                                 Blflag = TRUE;
1682                         else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1683                                 Bgflag = TRUE;
1684                         else if (strcmp(optarg,
1685                             MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1686                                 Beflag = TRUE;
1687                         else if (strcmp(optarg,
1688                             MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
1689                                 ld_eprintf(ofl, ERR_WARNING,
1690                                     MSG_INTL(MSG_ARG_UNSUPPORTED),
1691                                     MSG_ORIG(MSG_ARG_BTRANSLATOR));
1692                         } else if (strcmp(optarg,
1693                             MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1694                             strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1695                                 ld_eprintf(ofl, ERR_FATAL,
1696                                     MSG_INTL(MSG_ARG_ILLEGAL),
1697                                     MSG_ORIG(MSG_ARG_CB), optarg);
1698                         }
1699                         break;
1700 
1701                 case 'G':
1702                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1703                         otype = OT_SHARED;
1704                         break;
1705 
1706                 case 'L':
1707                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1708                         break;
1709 
1710                 case 'M':
1711                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1712                         if (aplist_append(&(ofl->ofl_maps), optarg,
1713                             AL_CNT_OFL_MAPFILES) == NULL)
1714                                 return (S_ERROR);
1715                         break;
1716 
1717                 case 'N':
1718                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1719                         break;
1720 
1721                 case 'Q':
1722                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1723                         if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1724                                 if (Qflag != SET_UNKNOWN)
1725                                         ld_eprintf(ofl, ERR_WARNING_NF,
1726                                             MSG_INTL(MSG_ARG_MTONCE),
1727                                             MSG_ORIG(MSG_ARG_CQ));
1728                                 else
1729                                         Qflag = SET_FALSE;
1730                         } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1731                                 if (Qflag != SET_UNKNOWN)
1732                                         ld_eprintf(ofl, ERR_WARNING_NF,
1733                                             MSG_INTL(MSG_ARG_MTONCE),
1734                                             MSG_ORIG(MSG_ARG_CQ));
1735                                 else
1736                                         Qflag = SET_TRUE;
1737                         } else {
1738                                 ld_eprintf(ofl, ERR_FATAL,
1739                                     MSG_INTL(MSG_ARG_ILLEGAL),
1740                                     MSG_ORIG(MSG_ARG_CQ), optarg);
1741                         }
1742                         break;
1743 
1744                 case 'S':
1745                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1746                         if (aplist_append(&lib_support, optarg,
1747                             AL_CNT_SUPPORT) == NULL)
1748                                 return (S_ERROR);
1749                         break;
1750 
1751                 case 'V':
1752                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1753                         if (!Vflag)
1754                                 (void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1755                                     ofl->ofl_sgsid);
1756                         Vflag = TRUE;
1757                         break;
1758 
1759                 case 'Y':
1760                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1761                         if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1762                                 if (Llibdir)
1763                                         ld_eprintf(ofl, ERR_WARNING_NF,
1764                                             MSG_INTL(MSG_ARG_MTONCE),
1765                                             MSG_ORIG(MSG_ARG_CYL));
1766                                 else
1767                                         Llibdir = optarg + 2;
1768                         } else if (strncmp(optarg,
1769                             MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1770                                 if (Ulibdir)
1771                                         ld_eprintf(ofl, ERR_WARNING_NF,
1772                                             MSG_INTL(MSG_ARG_MTONCE),
1773                                             MSG_ORIG(MSG_ARG_CYU));
1774                                 else
1775                                         Ulibdir = optarg + 2;
1776                         } else if (strncmp(optarg,
1777                             MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1778                                 if (Plibpath)
1779                                         ld_eprintf(ofl, ERR_WARNING_NF,
1780                                             MSG_INTL(MSG_ARG_MTONCE),
1781                                             MSG_ORIG(MSG_ARG_CYP));
1782                                 else
1783                                         Plibpath = optarg + 2;
1784                         } else {
1785                                 ld_eprintf(ofl, ERR_FATAL,
1786                                     MSG_INTL(MSG_ARG_ILLEGAL),
1787                                     MSG_ORIG(MSG_ARG_CY), optarg);
1788                         }
1789                         break;
1790 
1791                 case '?':
1792                         DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1793                         /*
1794                          * If the option character is '-', we're looking at a
1795                          * long option which couldn't be translated, display a
1796                          * more useful error.
1797                          */
1798                         if (optopt == '-') {
1799                                 eprintf(ofl->ofl_lml, ERR_FATAL,
1800                                     MSG_INTL(MSG_ARG_LONG_UNKNOWN),
1801                                     argv[optind-1]);
1802                         } else {
1803                                 eprintf(ofl->ofl_lml, ERR_FATAL,
1804                                     MSG_INTL(MSG_ARG_UNKNOWN), optopt);
1805                         }
1806                         (*usage)++;
1807                         break;
1808 
1809                 default:
1810                         break;
1811                 }
1812 
1813                 /*
1814                  * Update the argument index for the next getopt() iteration.
1815                  */
1816                 ndx = optind;
1817         }
1818         return (1);
1819 }
1820 
1821 /*
1822  * Parsing options pass2 for
1823  */
1824 static uintptr_t
1825 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1826 {
1827         int     c, ndx = optind;
1828 
1829         while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1830                 Ifl_desc        *ifl;
1831                 Sym_desc        *sdp;
1832 
1833                 switch (c) {
1834                         case 'l':
1835                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1836                                     optarg));
1837                                 if (ld_find_library(optarg, ofl) == S_ERROR)
1838                                         return (S_ERROR);
1839                                 break;
1840                         case 'B':
1841                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1842                                     optarg));
1843                                 if (strcmp(optarg,
1844                                     MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1845                                         if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1846                                                 ofl->ofl_flags |=
1847                                                     FLG_OF_DYNLIBS;
1848                                         else {
1849                                                 ld_eprintf(ofl, ERR_FATAL,
1850                                                     MSG_INTL(MSG_ARG_ST_INCOMP),
1851                                                     MSG_ORIG(MSG_ARG_BDYNAMIC));
1852                                         }
1853                                 } else if (strcmp(optarg,
1854                                     MSG_ORIG(MSG_ARG_STATIC)) == 0)
1855                                         ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1856                                 break;
1857                         case 'L':
1858                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1859                                     optarg));
1860                                 if (ld_add_libdir(ofl, optarg) == S_ERROR)
1861                                         return (S_ERROR);
1862                                 break;
1863                         case 'N':
1864                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1865                                     optarg));
1866                                 /*
1867                                  * Record DT_NEEDED string
1868                                  */
1869                                 if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
1870                                         ld_eprintf(ofl, ERR_FATAL,
1871                                             MSG_INTL(MSG_ARG_ST_INCOMP),
1872                                             MSG_ORIG(MSG_ARG_CN));
1873                                 if (((ifl = libld_calloc(1,
1874                                     sizeof (Ifl_desc))) == NULL) ||
1875                                     (aplist_append(&ofl->ofl_sos, ifl,
1876                                     AL_CNT_OFL_LIBS) == NULL))
1877                                         return (S_ERROR);
1878 
1879                                 ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1880                                 ifl->ifl_soname = optarg;
1881                                 ifl->ifl_flags = (FLG_IF_NEEDSTR |
1882                                     FLG_IF_FILEREF | FLG_IF_DEPREQD);
1883 
1884                                 break;
1885                         case 'D':
1886                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1887                                     optarg));
1888                                 (void) dbg_setup(ofl, optarg, 3);
1889                                 break;
1890                         case 'u':
1891                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1892                                     optarg));
1893                                 if (ld_sym_add_u(optarg, ofl,
1894                                     MSG_STR_COMMAND) == (Sym_desc *)S_ERROR)
1895                                         return (S_ERROR);
1896                                 break;
1897                         case 'z':
1898                                 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1899                                     optarg));
1900                                 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1901                                     MSG_ARG_LD32_SIZE) == 0) ||
1902                                     (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1903                                     MSG_ARG_LD64_SIZE) == 0)) {
1904                                         if (createargv(ofl, 0) == S_ERROR)
1905                                                 return (S_ERROR);
1906                                 } else if (strcmp(optarg,
1907                                     MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1908                                         ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1909                                         ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1910                                 } else if (strcmp(optarg,
1911                                     MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1912                                         ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1913                                         ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1914                                 } else if (strcmp(optarg,
1915                                     MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1916                                         ofl->ofl_flags1 &=
1917                                             ~(FLG_OF1_ALLEXRT |
1918                                             FLG_OF1_WEAKEXT);
1919                                 } else if (strcmp(optarg,
1920                                     MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1921                                         ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1922                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1923                                 } else if (strcmp(optarg,
1924                                     MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1925                                         ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1926                                         ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1927                                 } else if (strcmp(optarg,
1928                                     MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1929                                         ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1930                                 } else if (strcmp(optarg,
1931                                     MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1932                                         ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1933                                 } else if (strcmp(optarg,
1934                                     MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1935                                         ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1936                                         ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1937                                 } else if (strcmp(optarg,
1938                                     MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1939                                         ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1940                                         ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1941                                 } else if (strcmp(optarg,
1942                                     MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1943                                         ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1944                                 } else if (strcmp(optarg,
1945                                     MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1946                                         ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1947                                 } else if (strncmp(optarg,
1948                                     MSG_ORIG(MSG_ARG_INITARRAY),
1949                                     MSG_ARG_INITARRAY_SIZE) == 0) {
1950                                         if (((sdp = ld_sym_add_u(optarg +
1951                                             MSG_ARG_INITARRAY_SIZE, ofl,
1952                                             MSG_STR_COMMAND)) ==
1953                                             (Sym_desc *)S_ERROR) ||
1954                                             (aplist_append(&ofl->ofl_initarray,
1955                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1956                                                 return (S_ERROR);
1957                                 } else if (strncmp(optarg,
1958                                     MSG_ORIG(MSG_ARG_FINIARRAY),
1959                                     MSG_ARG_FINIARRAY_SIZE) == 0) {
1960                                         if (((sdp = ld_sym_add_u(optarg +
1961                                             MSG_ARG_FINIARRAY_SIZE, ofl,
1962                                             MSG_STR_COMMAND)) ==
1963                                             (Sym_desc *)S_ERROR) ||
1964                                             (aplist_append(&ofl->ofl_finiarray,
1965                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1966                                                 return (S_ERROR);
1967                                 } else if (strncmp(optarg,
1968                                     MSG_ORIG(MSG_ARG_PREINITARRAY),
1969                                     MSG_ARG_PREINITARRAY_SIZE) == 0) {
1970                                         if (((sdp = ld_sym_add_u(optarg +
1971                                             MSG_ARG_PREINITARRAY_SIZE, ofl,
1972                                             MSG_STR_COMMAND)) ==
1973                                             (Sym_desc *)S_ERROR) ||
1974                                             (aplist_append(&ofl->ofl_preiarray,
1975                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1976                                                 return (S_ERROR);
1977                                 } else if (strncmp(optarg,
1978                                     MSG_ORIG(MSG_ARG_RTLDINFO),
1979                                     MSG_ARG_RTLDINFO_SIZE) == 0) {
1980                                         if (((sdp = ld_sym_add_u(optarg +
1981                                             MSG_ARG_RTLDINFO_SIZE, ofl,
1982                                             MSG_STR_COMMAND)) ==
1983                                             (Sym_desc *)S_ERROR) ||
1984                                             (aplist_append(&ofl->ofl_rtldinfo,
1985                                             sdp, AL_CNT_OFL_ARRAYS) == NULL))
1986                                                 return (S_ERROR);
1987                                 } else if (strncmp(optarg,
1988                                     MSG_ORIG(MSG_ARG_DTRACE),
1989                                     MSG_ARG_DTRACE_SIZE) == 0) {
1990                                         if ((sdp = ld_sym_add_u(optarg +
1991                                             MSG_ARG_DTRACE_SIZE, ofl,
1992                                             MSG_STR_COMMAND)) ==
1993                                             (Sym_desc *)S_ERROR)
1994                                                 return (S_ERROR);
1995                                         ofl->ofl_dtracesym = sdp;
1996                                 } else if (strcmp(optarg,
1997                                     MSG_ORIG(MSG_ARG_RESCAN_NOW)) == 0) {
1998                                         if (ld_rescan_archives(ofl, 0, ndx) ==
1999                                             S_ERROR)
2000                                                 return (S_ERROR);
2001                                 } else if (strcmp(optarg,
2002                                     MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
2003                                         ofl->ofl_ars_gsndx = ofl->ofl_arscnt;
2004                                         ofl->ofl_ars_gsandx = ndx;
2005                                 } else if (strcmp(optarg,
2006                                     MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
2007                                         if (ld_rescan_archives(ofl, 1, ndx) ==
2008                                             S_ERROR)
2009                                                 return (S_ERROR);
2010                                 } else if (strcmp(optarg,
2011                                     MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
2012                                         ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
2013                                 } else if (strcmp(optarg,
2014                                     MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
2015                                         ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
2016                                 }
2017                         default:
2018                                 break;
2019                 }
2020 
2021                 /*
2022                  * Update the argument index for the next getopt() iteration.
2023                  */
2024                 ndx = optind;
2025         }
2026         return (1);
2027 }
2028 
2029 /*
2030  *
2031  * Pass 1 -- process_flags: collects all options and sets flags
2032  */
2033 static uintptr_t
2034 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
2035 {
2036         for (; optind < argc; optind++) {
2037                 /*
2038                  * If we detect some more options return to getopt().
2039                  * Checking argv[optind][1] against null prevents a forever
2040                  * loop if an unadorned `-' argument is passed to us.
2041                  */
2042                 while ((optind < argc) && (argv[optind][0] == '-')) {
2043                         if (argv[optind][1] != '\0') {
2044                                 if (parseopt_pass1(ofl, argc, argv,
2045                                     usage) == S_ERROR)
2046                                         return (S_ERROR);
2047                         } else if (++optind < argc)
2048                                 continue;
2049                 }
2050                 if (optind >= argc)
2051                         break;
2052                 ofl->ofl_objscnt++;
2053         }
2054 
2055         /* Did an unterminated archive group run off the end? */
2056         if (ofl->ofl_ars_gsandx > 0) {
2057                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
2058                     MSG_INTL(MSG_MARG_AR_GRP_START),
2059                     MSG_INTL(MSG_MARG_AR_GRP_END));
2060                 return (S_ERROR);
2061         }
2062 
2063         return (1);
2064 }
2065 
2066 uintptr_t
2067 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
2068 {
2069         int     usage = 0;      /* Collect all argument errors before exit */
2070 
2071         if (argc < 2) {
2072                 usage_mesg(FALSE);
2073                 return (S_ERROR);
2074         }
2075 
2076         /*
2077          * Option handling
2078          */
2079         opterr = 0;
2080         optind = 1;
2081         if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
2082                 return (S_ERROR);
2083 
2084         /*
2085          * Having parsed everything, did we have any usage errors.
2086          */
2087         if (usage) {
2088                 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
2089                 return (S_ERROR);
2090         }
2091 
2092         return (check_flags(ofl, argc));
2093 }
2094 
2095 /*
2096  * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
2097  * files.
2098  */
2099 static uintptr_t
2100 process_files_com(Ofl_desc *ofl, int argc, char **argv)
2101 {
2102         for (; optind < argc; optind++) {
2103                 int             fd;
2104                 uintptr_t       open_ret;
2105                 char            *path;
2106                 Rej_desc        rej = { 0 };
2107 
2108                 /*
2109                  * If we detect some more options return to getopt().
2110                  * Checking argv[optind][1] against null prevents a forever
2111                  * loop if an unadorned `-' argument is passed to us.
2112                  */
2113                 while ((optind < argc) && (argv[optind][0] == '-')) {
2114                         if (argv[optind][1] != '\0') {
2115                                 if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
2116                                         return (S_ERROR);
2117                         } else if (++optind < argc)
2118                                 continue;
2119                 }
2120                 if (optind >= argc)
2121                         break;
2122 
2123                 path = argv[optind];
2124                 if ((fd = open(path, O_RDONLY)) == -1) {
2125                         int err = errno;
2126 
2127                         ld_eprintf(ofl, ERR_FATAL,
2128                             MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
2129                         continue;
2130                 }
2131 
2132                 DBG_CALL(Dbg_args_file(ofl->ofl_lml, optind, path));
2133 
2134                 open_ret = ld_process_open(path, path, &fd, ofl,
2135                     (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej, NULL);
2136                 if (fd != -1)
2137                         (void) close(fd);
2138                 if (open_ret == S_ERROR)
2139                         return (S_ERROR);
2140 
2141                 /*
2142                  * Check for mismatched input.
2143                  */
2144                 if (rej.rej_type) {
2145                         Conv_reject_desc_buf_t rej_buf;
2146 
2147                         ld_eprintf(ofl, ERR_FATAL,
2148                             MSG_INTL(reject[rej.rej_type]),
2149                             rej.rej_name ? rej.rej_name :
2150                             MSG_INTL(MSG_STR_UNKNOWN),
2151                             conv_reject_desc(&rej, &rej_buf,
2152                             ld_targ.t_m.m_mach));
2153                         return (1);
2154                 }
2155         }
2156         return (1);
2157 }
2158 
2159 uintptr_t
2160 ld_process_files(Ofl_desc *ofl, int argc, char **argv)
2161 {
2162         DBG_CALL(Dbg_basic_files(ofl->ofl_lml));
2163 
2164         /*
2165          * Process command line files (taking into account any applicable
2166          * preceding flags).  Return if any fatal errors have occurred.
2167          */
2168         opterr = 0;
2169         optind = 1;
2170         if (process_files_com(ofl, argc, argv) == S_ERROR)
2171                 return (S_ERROR);
2172         if (ofl->ofl_flags & FLG_OF_FATAL)
2173                 return (1);
2174 
2175         /*
2176          * Guidance: Use -B direct/nodirect or -z direct/nodirect.
2177          *
2178          * This is a backstop for the case where the link had no dependencies.
2179          * Otherwise, it will get caught by ld_process_ifl(). We need both,
2180          * because -z direct is positional, and its value at the time where
2181          * the first dependency is seen might be different than it is now.
2182          */
2183         if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
2184             OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
2185                 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
2186                 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
2187         }
2188 
2189         /*
2190          * Now that all command line files have been processed see if there are
2191          * any additional `needed' shared object dependencies.
2192          */
2193         if (ofl->ofl_soneed)
2194                 if (ld_finish_libs(ofl) == S_ERROR)
2195                         return (S_ERROR);
2196 
2197         /*
2198          * If rescanning archives is enabled, do so now to determine whether
2199          * there might still be members extracted to satisfy references from any
2200          * explicit objects.  Continue until no new objects are extracted.  Note
2201          * that this pass is carried out *after* processing any implicit objects
2202          * (above) as they may already have resolved any undefined references
2203          * from any explicit dependencies.
2204          */
2205         if (ofl->ofl_flags1 & FLG_OF1_RESCAN) {
2206                 if (ld_rescan_archives(ofl, 0, argc) == S_ERROR)
2207                         return (S_ERROR);
2208                 if (ofl->ofl_flags & FLG_OF_FATAL)
2209                         return (1);
2210         }
2211 
2212         /*
2213          * If debugging, provide statistics on each archives extraction, or flag
2214          * any archive that has provided no members.  Note that this could be a
2215          * nice place to free up much of the archive infrastructure, as we've
2216          * extracted any members we need.  However, as we presently don't free
2217          * anything under ld(1) there's not much point in proceeding further.
2218          */
2219         DBG_CALL(Dbg_statistics_ar(ofl));
2220 
2221         /*
2222          * If any version definitions have been established, either via input
2223          * from a mapfile or from the input relocatable objects, make sure any
2224          * version dependencies are satisfied, and version symbols created.
2225          */
2226         if (ofl->ofl_verdesc)
2227                 if (ld_vers_check_defs(ofl) == S_ERROR)
2228                         return (S_ERROR);
2229 
2230         /*
2231          * If input section ordering was specified within some segment
2232          * using a mapfile, verify that the expected sections were seen.
2233          */
2234         if (ofl->ofl_flags & FLG_OF_IS_ORDER)
2235                 ld_ent_check(ofl);
2236 
2237         return (1);
2238 }
2239 
2240 uintptr_t
2241 ld_init_strings(Ofl_desc *ofl)
2242 {
2243         uint_t  stflags;
2244 
2245         if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
2246                 stflags = 0;
2247         else
2248                 stflags = FLG_STNEW_COMPRESS;
2249 
2250         if (((ofl->ofl_shdrsttab = st_new(stflags)) == NULL) ||
2251             ((ofl->ofl_strtab = st_new(stflags)) == NULL) ||
2252             ((ofl->ofl_dynstrtab = st_new(stflags)) == NULL))
2253                 return (S_ERROR);
2254 
2255         return (0);
2256 }