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