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