xref: /illumos-gate/usr/src/cmd/sgs/libld/common/args.c (revision 8533946bd264dca901fdf56bf3da1d81e728b423)
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, MSG_INTL(MSG_ARG_ILLEGAL),
944 			    MSG_ORIG(MSG_ARG_ASSDEFLIB), optarg);
945 			return (TRUE);
946 		}
947 
948 		if (strncmp(optarg + MSG_ARG_ASSDEFLIB_SIZE + 1,
949 		    MSG_ORIG(MSG_STR_LIB), MSG_STR_LIB_SIZE) != 0 ||
950 		    strcmp(optarg + olen - MSG_STR_SOEXT_SIZE,
951 		    MSG_ORIG(MSG_STR_SOEXT)) != 0 || olen <= mlen) {
952 			ld_eprintf(ofl, ERR_FATAL,
953 			    MSG_INTL(MSG_ARG_ASSDEFLIB_MALFORMED), optarg);
954 			return (TRUE);
955 		}
956 
957 		if (aplist_append(&ofl->ofl_assdeflib, optarg +
958 		    MSG_ARG_ASSDEFLIB_SIZE + 1, AL_CNT_ASSDEFLIB) == NULL)
959 			return (FALSE);
960 	}
961 
962 	return (TRUE);
963 }
964 
965 static int	optitle = 0;
966 /*
967  * Parsing options pass1 for process_flags().
968  */
969 static uintptr_t
970 parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
971 {
972 	int	c, ndx = optind;
973 
974 	/*
975 	 * The -32, -64 and -ztarget options are special, in that we validate
976 	 * them, but otherwise ignore them. libld.so (this code) is called
977 	 * from the ld front end program. ld has already examined the
978 	 * arguments to determine the output class and machine type of the
979 	 * output object, as reflected in the version (32/64) of ld_main()
980 	 * that was called and the value of the 'mach' argument passed.
981 	 * By time execution reaches this point, these options have already
982 	 * been seen and acted on.
983 	 */
984 	while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
985 
986 		switch (c) {
987 		case '3':
988 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
989 
990 			/*
991 			 * -32 is processed by ld to determine the output class.
992 			 * Here we sanity check the option incase some other
993 			 * -3* option is mistakenly passed to us.
994 			 */
995 			if (optarg[0] != '2')
996 				ld_eprintf(ofl, ERR_FATAL,
997 				    MSG_INTL(MSG_ARG_ILLEGAL),
998 				    MSG_ORIG(MSG_ARG_3), optarg);
999 			continue;
1000 
1001 		case '6':
1002 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1003 
1004 			/*
1005 			 * -64 is processed by ld to determine the output class.
1006 			 * Here we sanity check the option incase some other
1007 			 * -6* option is mistakenly passed to us.
1008 			 */
1009 			if (optarg[0] != '4')
1010 				ld_eprintf(ofl, ERR_FATAL,
1011 				    MSG_INTL(MSG_ARG_ILLEGAL),
1012 				    MSG_ORIG(MSG_ARG_6), optarg);
1013 			continue;
1014 
1015 		case 'a':
1016 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1017 			aflag = TRUE;
1018 			break;
1019 
1020 		case 'b':
1021 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1022 			bflag = TRUE;
1023 
1024 			/*
1025 			 * This is a hack, and may be undone later.
1026 			 * The -b option is only used to build the Unix
1027 			 * kernel and its related kernel-mode modules.
1028 			 * We do not want those files to get a .SUNW_ldynsym
1029 			 * section. At least for now, the kernel makes no
1030 			 * use of .SUNW_ldynsym, and we do not want to use
1031 			 * the space to hold it. Therefore, we overload
1032 			 * the use of -b to also imply -znoldynsym.
1033 			 */
1034 			ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1035 			break;
1036 
1037 		case 'c':
1038 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1039 			if (ofl->ofl_config)
1040 				ld_eprintf(ofl, ERR_WARNING_NF,
1041 				    MSG_INTL(MSG_ARG_MTONCE),
1042 				    MSG_ORIG(MSG_ARG_C));
1043 			else
1044 				ofl->ofl_config = optarg;
1045 			break;
1046 
1047 		case 'C':
1048 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1049 			demangle_flag = 1;
1050 			break;
1051 
1052 		case 'd':
1053 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1054 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1055 				if (dflag != SET_UNKNOWN)
1056 					ld_eprintf(ofl, ERR_WARNING_NF,
1057 					    MSG_INTL(MSG_ARG_MTONCE),
1058 					    MSG_ORIG(MSG_ARG_D));
1059 				else
1060 					dflag = SET_FALSE;
1061 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1062 				if (dflag != SET_UNKNOWN)
1063 					ld_eprintf(ofl, ERR_WARNING_NF,
1064 					    MSG_INTL(MSG_ARG_MTONCE),
1065 					    MSG_ORIG(MSG_ARG_D));
1066 				else
1067 					dflag = SET_TRUE;
1068 			} else {
1069 				ld_eprintf(ofl, ERR_FATAL,
1070 				    MSG_INTL(MSG_ARG_ILLEGAL),
1071 				    MSG_ORIG(MSG_ARG_D), optarg);
1072 			}
1073 			break;
1074 
1075 		case 'e':
1076 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1077 			if (ofl->ofl_entry)
1078 				ld_eprintf(ofl, ERR_WARNING_NF,
1079 				    MSG_INTL(MSG_MARG_MTONCE),
1080 				    MSG_INTL(MSG_MARG_ENTRY));
1081 			else
1082 				ofl->ofl_entry = (void *)optarg;
1083 			break;
1084 
1085 		case 'f':
1086 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1087 			if (ofl->ofl_filtees &&
1088 			    (!(ofl->ofl_flags & FLG_OF_AUX))) {
1089 				ld_eprintf(ofl, ERR_FATAL,
1090 				    MSG_INTL(MSG_MARG_INCOMP),
1091 				    MSG_INTL(MSG_MARG_FILTER_AUX),
1092 				    MSG_INTL(MSG_MARG_FILTER));
1093 			} else {
1094 				if ((ofl->ofl_filtees =
1095 				    add_string(ofl->ofl_filtees, optarg)) ==
1096 				    (const char *)S_ERROR)
1097 					return (S_ERROR);
1098 				ofl->ofl_flags |= FLG_OF_AUX;
1099 			}
1100 			break;
1101 
1102 		case 'F':
1103 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1104 			if (ofl->ofl_filtees &&
1105 			    (ofl->ofl_flags & FLG_OF_AUX)) {
1106 				ld_eprintf(ofl, ERR_FATAL,
1107 				    MSG_INTL(MSG_MARG_INCOMP),
1108 				    MSG_INTL(MSG_MARG_FILTER),
1109 				    MSG_INTL(MSG_MARG_FILTER_AUX));
1110 			} else {
1111 				if ((ofl->ofl_filtees =
1112 				    add_string(ofl->ofl_filtees, optarg)) ==
1113 				    (const char *)S_ERROR)
1114 					return (S_ERROR);
1115 			}
1116 			break;
1117 
1118 		case 'h':
1119 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1120 			if (ofl->ofl_soname)
1121 				ld_eprintf(ofl, ERR_WARNING_NF,
1122 				    MSG_INTL(MSG_MARG_MTONCE),
1123 				    MSG_INTL(MSG_MARG_SONAME));
1124 			else
1125 				ofl->ofl_soname = (const char *)optarg;
1126 			break;
1127 
1128 		case 'i':
1129 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1130 			ofl->ofl_flags |= FLG_OF_IGNENV;
1131 			break;
1132 
1133 		case 'I':
1134 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1135 			if (ofl->ofl_interp)
1136 				ld_eprintf(ofl, ERR_WARNING_NF,
1137 				    MSG_INTL(MSG_ARG_MTONCE),
1138 				    MSG_ORIG(MSG_ARG_CI));
1139 			else
1140 				ofl->ofl_interp = (const char *)optarg;
1141 			break;
1142 
1143 		case 'l':
1144 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1145 			/*
1146 			 * For now, count any library as a shared object.  This
1147 			 * is used to size the internal symbol cache.  This
1148 			 * value is recalculated later on actual file processing
1149 			 * to get an accurate shared object count.
1150 			 */
1151 			ofl->ofl_soscnt++;
1152 			break;
1153 
1154 		case 'm':
1155 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1156 			ofl->ofl_flags |= FLG_OF_GENMAP;
1157 			break;
1158 
1159 		case 'o':
1160 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1161 			if (ofl->ofl_name)
1162 				ld_eprintf(ofl, ERR_WARNING_NF,
1163 				    MSG_INTL(MSG_MARG_MTONCE),
1164 				    MSG_INTL(MSG_MARG_OUTFILE));
1165 			else
1166 				ofl->ofl_name = (const char *)optarg;
1167 			break;
1168 
1169 		case 'p':
1170 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1171 
1172 			/*
1173 			 * Multiple instances of this option may occur.  Each
1174 			 * additional instance is effectively concatenated to
1175 			 * the previous separated by a colon.
1176 			 */
1177 			if (*optarg != '\0') {
1178 				if ((ofl->ofl_audit =
1179 				    add_string(ofl->ofl_audit,
1180 				    optarg)) == (const char *)S_ERROR)
1181 					return (S_ERROR);
1182 			}
1183 			break;
1184 
1185 		case 'P':
1186 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1187 
1188 			/*
1189 			 * Multiple instances of this option may occur.  Each
1190 			 * additional instance is effectively concatenated to
1191 			 * the previous separated by a colon.
1192 			 */
1193 			if (*optarg != '\0') {
1194 				if ((ofl->ofl_depaudit =
1195 				    add_string(ofl->ofl_depaudit,
1196 				    optarg)) == (const char *)S_ERROR)
1197 					return (S_ERROR);
1198 			}
1199 			break;
1200 
1201 		case 'r':
1202 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1203 			rflag = TRUE;
1204 			break;
1205 
1206 		case 'R':
1207 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1208 
1209 			/*
1210 			 * Multiple instances of this option may occur.  Each
1211 			 * additional instance is effectively concatenated to
1212 			 * the previous separated by a colon.
1213 			 */
1214 			if (*optarg != '\0') {
1215 				if ((ofl->ofl_rpath =
1216 				    add_string(ofl->ofl_rpath,
1217 				    optarg)) == (const char *)S_ERROR)
1218 					return (S_ERROR);
1219 			}
1220 			break;
1221 
1222 		case 's':
1223 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1224 			sflag = TRUE;
1225 			break;
1226 
1227 		case 't':
1228 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1229 			ofl->ofl_flags |= FLG_OF_NOWARN;
1230 			break;
1231 
1232 		case 'u':
1233 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1234 			break;
1235 
1236 		case 'z':
1237 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1238 
1239 			/*
1240 			 * For specific help, print our usage message and exit
1241 			 * immediately to ensure a 0 return code.
1242 			 */
1243 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
1244 			    MSG_ARG_HELP_SIZE) == 0) {
1245 				usage_mesg(TRUE);
1246 				exit(0);
1247 			}
1248 
1249 			/*
1250 			 * For some options set a flag - further consistancy
1251 			 * checks will be carried out in check_flags().
1252 			 */
1253 			if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1254 			    MSG_ARG_LD32_SIZE) == 0) ||
1255 			    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1256 			    MSG_ARG_LD64_SIZE) == 0)) {
1257 				if (createargv(ofl, usage) == S_ERROR)
1258 					return (S_ERROR);
1259 
1260 			} else if (
1261 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
1262 				if (zdflag != SET_UNKNOWN)
1263 					ld_eprintf(ofl, ERR_WARNING_NF,
1264 					    MSG_INTL(MSG_ARG_MTONCE),
1265 					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
1266 				else
1267 					zdflag = SET_TRUE;
1268 				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1269 			} else if (strcmp(optarg,
1270 			    MSG_ORIG(MSG_ARG_NODEFS)) == 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_FALSE;
1277 				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1278 			} else if (strcmp(optarg,
1279 			    MSG_ORIG(MSG_ARG_TEXT)) == 0) {
1280 				if (ztflag &&
1281 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT)))
1282 					ld_eprintf(ofl, ERR_FATAL,
1283 					    MSG_INTL(MSG_ARG_INCOMP),
1284 					    MSG_ORIG(MSG_ARG_ZTEXT),
1285 					    ztflag);
1286 				ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
1287 			} else if (strcmp(optarg,
1288 			    MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
1289 				if (ztflag &&
1290 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF)))
1291 					ld_eprintf(ofl, ERR_FATAL,
1292 					    MSG_INTL(MSG_ARG_INCOMP),
1293 					    MSG_ORIG(MSG_ARG_ZTEXTOFF),
1294 					    ztflag);
1295 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
1296 			} else if (strcmp(optarg,
1297 			    MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
1298 				if (ztflag &&
1299 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN)))
1300 					ld_eprintf(ofl, ERR_FATAL,
1301 					    MSG_INTL(MSG_ARG_INCOMP),
1302 					    MSG_ORIG(MSG_ARG_ZTEXTWARN),
1303 					    ztflag);
1304 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
1305 
1306 			/*
1307 			 * For other options simply set the ofl flags directly.
1308 			 */
1309 			} else if (strcmp(optarg,
1310 			    MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
1311 				ofl->ofl_flags1 |= FLG_OF1_RESCAN;
1312 			} else if (strcmp(optarg,
1313 			    MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
1314 				ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
1315 			} else if (strcmp(optarg,
1316 			    MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
1317 				zlflag = TRUE;
1318 			} else if (strcmp(optarg,
1319 			    MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
1320 				ofl->ofl_dtflags_1 |= DF_1_NORELOC;
1321 			} else if (strcmp(optarg,
1322 			    MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
1323 				ofl->ofl_flags |= FLG_OF_NOVERSEC;
1324 			} else if (strcmp(optarg,
1325 			    MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
1326 				ofl->ofl_flags |= FLG_OF_MULDEFS;
1327 			} else if (strcmp(optarg,
1328 			    MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
1329 				ofl->ofl_flags |= FLG_OF_REDLSYM;
1330 			} else if (strcmp(optarg,
1331 			    MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
1332 				ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
1333 			} else if (strcmp(optarg,
1334 			    MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
1335 				ofl->ofl_dtflags_1 |= DF_1_NODELETE;
1336 			} else if (strcmp(optarg,
1337 			    MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
1338 				ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
1339 			} else if (strcmp(optarg,
1340 			    MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
1341 				ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
1342 			} else if (strcmp(optarg,
1343 			    MSG_ORIG(MSG_ARG_NOW)) == 0) {
1344 				ofl->ofl_dtflags_1 |= DF_1_NOW;
1345 				ofl->ofl_dtflags |= DF_BIND_NOW;
1346 			} else if (strcmp(optarg,
1347 			    MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
1348 				ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
1349 				ofl->ofl_dtflags |= DF_ORIGIN;
1350 			} else if (strcmp(optarg,
1351 			    MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1352 				ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1353 			} else if (strcmp(optarg,
1354 			    MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1355 				ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1356 			} else if (strcmp(optarg,
1357 			    MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1358 				ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1359 			} else if (strcmp(optarg,
1360 			    MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1361 				ofl->ofl_flags |= FLG_OF_VERBOSE;
1362 			} else if (strcmp(optarg,
1363 			    MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1364 				ofl->ofl_flags |= FLG_OF_COMREL;
1365 			} else if (strcmp(optarg,
1366 			    MSG_ORIG(MSG_ARG_NOCOMBRELOC)) == 0) {
1367 				ofl->ofl_flags |= FLG_OF_NOCOMREL;
1368 			} else if (strcmp(optarg,
1369 			    MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1370 				ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1371 			} else if (strcmp(optarg,
1372 			    MSG_ORIG(MSG_ARG_NOINTERP)) == 0) {
1373 				ofl->ofl_flags1 |= FLG_OF1_NOINTRP;
1374 			} else if (strcmp(optarg,
1375 			    MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1376 				zinflag = TRUE;
1377 			} else if (strcmp(optarg,
1378 			    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1379 				ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1380 			} else if (strcmp(optarg,
1381 			    MSG_ORIG(MSG_ARG_RELAXRELOC)) == 0) {
1382 				ofl->ofl_flags1 |= FLG_OF1_RLXREL;
1383 			} else if (strcmp(optarg,
1384 			    MSG_ORIG(MSG_ARG_NORELAXRELOC)) == 0) {
1385 				ofl->ofl_flags1 |= FLG_OF1_NRLXREL;
1386 			} else if (strcmp(optarg,
1387 			    MSG_ORIG(MSG_ARG_NOLDYNSYM)) == 0) {
1388 				ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1389 			} else if (strcmp(optarg,
1390 			    MSG_ORIG(MSG_ARG_GLOBAUDIT)) == 0) {
1391 				ofl->ofl_dtflags_1 |= DF_1_GLOBAUDIT;
1392 			} else if (strcmp(optarg,
1393 			    MSG_ORIG(MSG_ARG_NOSIGHANDLER)) == 0) {
1394 				ofl->ofl_flags1 |= FLG_OF1_NOSGHND;
1395 			} else if (strcmp(optarg,
1396 			    MSG_ORIG(MSG_ARG_SYMBOLCAP)) == 0) {
1397 				ofl->ofl_flags |= FLG_OF_OTOSCAP;
1398 
1399 			/*
1400 			 * Check archive group usage
1401 			 *	-z rescan-start ... -z rescan-end
1402 			 * to ensure they don't overlap and are well formed.
1403 			 */
1404 			} else if (strcmp(optarg,
1405 			    MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1406 				if (ofl->ofl_ars_gsandx == 0) {
1407 					ofl->ofl_ars_gsandx = ndx;
1408 				} else if (ofl->ofl_ars_gsandx > 0) {
1409 					/* Another group is still open */
1410 					ld_eprintf(ofl, ERR_FATAL,
1411 					    MSG_INTL(MSG_ARG_AR_GRP_OLAP),
1412 					    MSG_INTL(MSG_MARG_AR_GRPS));
1413 					/* Don't report cascading errors */
1414 					ofl->ofl_ars_gsandx = -1;
1415 				}
1416 			} else if (strcmp(optarg,
1417 			    MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1418 				if (ofl->ofl_ars_gsandx > 0) {
1419 					ofl->ofl_ars_gsandx = 0;
1420 				} else if (ofl->ofl_ars_gsandx == 0) {
1421 					/* There was no matching begin */
1422 					ld_eprintf(ofl, ERR_FATAL,
1423 					    MSG_INTL(MSG_ARG_AR_GRP_BAD),
1424 					    MSG_INTL(MSG_MARG_AR_GRP_END),
1425 					    MSG_INTL(MSG_MARG_AR_GRP_START));
1426 					/* Don't report cascading errors */
1427 					ofl->ofl_ars_gsandx = -1;
1428 				}
1429 
1430 			/*
1431 			 * If -z wrap is seen, enter the symbol to be wrapped
1432 			 * into the wrap AVL tree.
1433 			 */
1434 			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_WRAP),
1435 			    MSG_ARG_WRAP_SIZE) == 0) {
1436 				if (ld_wrap_enter(ofl,
1437 				    optarg + MSG_ARG_WRAP_SIZE) == NULL)
1438 					return (S_ERROR);
1439 			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASLR),
1440 			    MSG_ARG_ASLR_SIZE) == 0) {
1441 				char *p = optarg + MSG_ARG_ASLR_SIZE;
1442 				if (*p == '\0') {
1443 					ofl->ofl_aslr = 1;
1444 				} else if (*p == '=') {
1445 					p++;
1446 
1447 					if ((strcmp(p,
1448 					    MSG_ORIG(MSG_ARG_ENABLED)) == 0) ||
1449 					    (strcmp(p,
1450 					    MSG_ORIG(MSG_ARG_ENABLE)) == 0)) {
1451 						ofl->ofl_aslr = 1;
1452 					} else if ((strcmp(p,
1453 					    MSG_ORIG(MSG_ARG_DISABLED)) == 0) ||
1454 					    (strcmp(p,
1455 					    MSG_ORIG(MSG_ARG_DISABLE)) == 0)) {
1456 						ofl->ofl_aslr = -1;
1457 					} else {
1458 						ld_eprintf(ofl, ERR_FATAL,
1459 						    MSG_INTL(MSG_ARG_ILLEGAL),
1460 						    MSG_ORIG(MSG_ARG_ZASLR), p);
1461 						return (S_ERROR);
1462 					}
1463 				} else {
1464 					ld_eprintf(ofl, ERR_FATAL,
1465 					    MSG_INTL(MSG_ARG_ILLEGAL),
1466 					    MSG_ORIG(MSG_ARG_Z), optarg);
1467 					return (S_ERROR);
1468 				}
1469 			} else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
1470 			    MSG_ARG_GUIDE_SIZE) == 0) &&
1471 			    ((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
1472 			    (optarg[MSG_ARG_GUIDE_SIZE] == '\0'))) {
1473 				if (!guidance_parse(ofl, optarg))
1474 					return (S_ERROR);
1475 			} else if (strcmp(optarg,
1476 			    MSG_ORIG(MSG_ARG_FATWARN)) == 0) {
1477 				if (zfwflag  == SET_FALSE) {
1478 					ld_eprintf(ofl, ERR_WARNING_NF,
1479 					    MSG_INTL(MSG_ARG_MTONCE),
1480 					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1481 				} else {
1482 					zfwflag = SET_TRUE;
1483 					ofl->ofl_flags |= FLG_OF_FATWARN;
1484 				}
1485 			} else if (strcmp(optarg,
1486 			    MSG_ORIG(MSG_ARG_NOFATWARN)) == 0) {
1487 				if (zfwflag  == SET_TRUE)
1488 					ld_eprintf(ofl, ERR_WARNING_NF,
1489 					    MSG_INTL(MSG_ARG_MTONCE),
1490 					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1491 				else
1492 					zfwflag = SET_FALSE;
1493 
1494 			/*
1495 			 * Process everything related to -z assert-deflib. This
1496 			 * must be done in pass 1 because it gets used in pass
1497 			 * 2.
1498 			 */
1499 			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASSDEFLIB),
1500 			    MSG_ARG_ASSDEFLIB_SIZE) == 0) {
1501 				if (assdeflib_parse(ofl, optarg) != TRUE)
1502 					return (S_ERROR);
1503 			/*
1504 			 * The following options just need validation as they
1505 			 * are interpreted on the second pass through the
1506 			 * command line arguments.
1507 			 */
1508 			} else if (
1509 			    strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1510 			    MSG_ARG_INITARRAY_SIZE) &&
1511 			    strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1512 			    MSG_ARG_FINIARRAY_SIZE) &&
1513 			    strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1514 			    MSG_ARG_PREINITARRAY_SIZE) &&
1515 			    strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1516 			    MSG_ARG_RTLDINFO_SIZE) &&
1517 			    strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1518 			    MSG_ARG_DTRACE_SIZE) &&
1519 			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1520 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1521 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1522 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1523 			    strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1524 			    strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1525 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1526 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1527 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
1528 			    strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1529 			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
1530 			    strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
1531 			    strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
1532 			    MSG_ARG_TARGET_SIZE) &&
1533 			    strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
1534 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
1535 				ld_eprintf(ofl, ERR_FATAL,
1536 				    MSG_INTL(MSG_ARG_ILLEGAL),
1537 				    MSG_ORIG(MSG_ARG_Z), optarg);
1538 			}
1539 
1540 			break;
1541 
1542 		case 'D':
1543 			/*
1544 			 * If we have not yet read any input files go ahead
1545 			 * and process any debugging options (this allows any
1546 			 * argument processing, entrance criteria and library
1547 			 * initialization to be displayed).  Otherwise, if an
1548 			 * input file has been seen, skip interpretation until
1549 			 * process_files (this allows debugging to be turned
1550 			 * on and off around individual groups of files).
1551 			 */
1552 			Dflag = 1;
1553 			if (ofl->ofl_objscnt == 0) {
1554 				if (dbg_setup(ofl, optarg, 2) == 0)
1555 					return (S_ERROR);
1556 			}
1557 
1558 			/*
1559 			 * A diagnostic can only be provided after dbg_setup().
1560 			 * As this is the first diagnostic that can be produced
1561 			 * by ld(1), issue a title for timing and basic output.
1562 			 */
1563 			if ((optitle == 0) && DBG_ENABLED) {
1564 				optitle++;
1565 				DBG_CALL(Dbg_basic_options(ofl->ofl_lml));
1566 			}
1567 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1568 			break;
1569 
1570 		case 'B':
1571 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1572 			if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1573 				if (Bdflag == SET_FALSE) {
1574 					ld_eprintf(ofl, ERR_FATAL,
1575 					    MSG_INTL(MSG_ARG_INCOMP),
1576 					    MSG_ORIG(MSG_ARG_BNODIRECT),
1577 					    MSG_ORIG(MSG_ARG_BDIRECT));
1578 				} else {
1579 					Bdflag = SET_TRUE;
1580 					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1581 				}
1582 			} else if (strcmp(optarg,
1583 			    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1584 				if (Bdflag == SET_TRUE) {
1585 					ld_eprintf(ofl, ERR_FATAL,
1586 					    MSG_INTL(MSG_ARG_INCOMP),
1587 					    MSG_ORIG(MSG_ARG_BDIRECT),
1588 					    MSG_ORIG(MSG_ARG_BNODIRECT));
1589 				} else {
1590 					Bdflag = SET_FALSE;
1591 					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1592 				}
1593 			} else if (strcmp(optarg,
1594 			    MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1595 				Bsflag = TRUE;
1596 			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1597 				ofl->ofl_flags |= FLG_OF_PROCRED;
1598 			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1599 				Blflag = TRUE;
1600 			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1601 				Bgflag = TRUE;
1602 			else if (strcmp(optarg,
1603 			    MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1604 				Beflag = TRUE;
1605 			else if (strcmp(optarg,
1606 			    MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
1607 				ld_eprintf(ofl, ERR_WARNING,
1608 				    MSG_INTL(MSG_ARG_UNSUPPORTED),
1609 				    MSG_ORIG(MSG_ARG_BTRANSLATOR));
1610 			} else if (strcmp(optarg,
1611 			    MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1612 			    strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1613 				ld_eprintf(ofl, ERR_FATAL,
1614 				    MSG_INTL(MSG_ARG_ILLEGAL),
1615 				    MSG_ORIG(MSG_ARG_CB), optarg);
1616 			}
1617 			break;
1618 
1619 		case 'G':
1620 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1621 			Gflag = TRUE;
1622 			break;
1623 
1624 		case 'L':
1625 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1626 			break;
1627 
1628 		case 'M':
1629 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1630 			if (aplist_append(&(ofl->ofl_maps), optarg,
1631 			    AL_CNT_OFL_MAPFILES) == NULL)
1632 				return (S_ERROR);
1633 			break;
1634 
1635 		case 'N':
1636 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1637 			break;
1638 
1639 		case 'Q':
1640 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1641 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1642 				if (Qflag != SET_UNKNOWN)
1643 					ld_eprintf(ofl, ERR_WARNING_NF,
1644 					    MSG_INTL(MSG_ARG_MTONCE),
1645 					    MSG_ORIG(MSG_ARG_CQ));
1646 				else
1647 					Qflag = SET_FALSE;
1648 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1649 				if (Qflag != SET_UNKNOWN)
1650 					ld_eprintf(ofl, ERR_WARNING_NF,
1651 					    MSG_INTL(MSG_ARG_MTONCE),
1652 					    MSG_ORIG(MSG_ARG_CQ));
1653 				else
1654 					Qflag = SET_TRUE;
1655 			} else {
1656 				ld_eprintf(ofl, ERR_FATAL,
1657 				    MSG_INTL(MSG_ARG_ILLEGAL),
1658 				    MSG_ORIG(MSG_ARG_CQ), optarg);
1659 			}
1660 			break;
1661 
1662 		case 'S':
1663 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1664 			if (aplist_append(&lib_support, optarg,
1665 			    AL_CNT_SUPPORT) == NULL)
1666 				return (S_ERROR);
1667 			break;
1668 
1669 		case 'V':
1670 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1671 			if (!Vflag)
1672 				(void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1673 				    ofl->ofl_sgsid);
1674 			Vflag = TRUE;
1675 			break;
1676 
1677 		case 'Y':
1678 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1679 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1680 				if (Llibdir)
1681 					ld_eprintf(ofl, ERR_WARNING_NF,
1682 					    MSG_INTL(MSG_ARG_MTONCE),
1683 					    MSG_ORIG(MSG_ARG_CYL));
1684 				else
1685 					Llibdir = optarg + 2;
1686 			} else if (strncmp(optarg,
1687 			    MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1688 				if (Ulibdir)
1689 					ld_eprintf(ofl, ERR_WARNING_NF,
1690 					    MSG_INTL(MSG_ARG_MTONCE),
1691 					    MSG_ORIG(MSG_ARG_CYU));
1692 				else
1693 					Ulibdir = optarg + 2;
1694 			} else if (strncmp(optarg,
1695 			    MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1696 				if (Plibpath)
1697 					ld_eprintf(ofl, ERR_WARNING_NF,
1698 					    MSG_INTL(MSG_ARG_MTONCE),
1699 					    MSG_ORIG(MSG_ARG_CYP));
1700 				else
1701 					Plibpath = optarg + 2;
1702 			} else {
1703 				ld_eprintf(ofl, ERR_FATAL,
1704 				    MSG_INTL(MSG_ARG_ILLEGAL),
1705 				    MSG_ORIG(MSG_ARG_CY), optarg);
1706 			}
1707 			break;
1708 
1709 		case '?':
1710 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1711 			/*
1712 			 * If the option character is '-', we're looking at a
1713 			 * long option which couldn't be translated, display a
1714 			 * more useful error.
1715 			 */
1716 			if (optopt == '-') {
1717 				eprintf(ofl->ofl_lml, ERR_FATAL,
1718 				    MSG_INTL(MSG_ARG_LONG_UNKNOWN),
1719 				    argv[optind-1]);
1720 			} else {
1721 				eprintf(ofl->ofl_lml, ERR_FATAL,
1722 				    MSG_INTL(MSG_ARG_UNKNOWN), optopt);
1723 			}
1724 			(*usage)++;
1725 			break;
1726 
1727 		default:
1728 			break;
1729 		}
1730 
1731 		/*
1732 		 * Update the argument index for the next getopt() iteration.
1733 		 */
1734 		ndx = optind;
1735 	}
1736 	return (1);
1737 }
1738 
1739 /*
1740  * Parsing options pass2 for
1741  */
1742 static uintptr_t
1743 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1744 {
1745 	int	c, ndx = optind;
1746 
1747 	while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1748 		Ifl_desc	*ifl;
1749 		Sym_desc	*sdp;
1750 
1751 		switch (c) {
1752 			case 'l':
1753 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1754 				    optarg));
1755 				if (ld_find_library(optarg, ofl) == S_ERROR)
1756 					return (S_ERROR);
1757 				break;
1758 			case 'B':
1759 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1760 				    optarg));
1761 				if (strcmp(optarg,
1762 				    MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1763 					if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1764 						ofl->ofl_flags |=
1765 						    FLG_OF_DYNLIBS;
1766 					else {
1767 						ld_eprintf(ofl, ERR_FATAL,
1768 						    MSG_INTL(MSG_ARG_ST_INCOMP),
1769 						    MSG_ORIG(MSG_ARG_BDYNAMIC));
1770 					}
1771 				} else if (strcmp(optarg,
1772 				    MSG_ORIG(MSG_ARG_STATIC)) == 0)
1773 					ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1774 				break;
1775 			case 'L':
1776 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1777 				    optarg));
1778 				if (ld_add_libdir(ofl, optarg) == S_ERROR)
1779 					return (S_ERROR);
1780 				break;
1781 			case 'N':
1782 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1783 				    optarg));
1784 				/*
1785 				 * Record DT_NEEDED string
1786 				 */
1787 				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
1788 					ld_eprintf(ofl, ERR_FATAL,
1789 					    MSG_INTL(MSG_ARG_ST_INCOMP),
1790 					    MSG_ORIG(MSG_ARG_CN));
1791 				if (((ifl = libld_calloc(1,
1792 				    sizeof (Ifl_desc))) == NULL) ||
1793 				    (aplist_append(&ofl->ofl_sos, ifl,
1794 				    AL_CNT_OFL_LIBS) == NULL))
1795 					return (S_ERROR);
1796 
1797 				ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1798 				ifl->ifl_soname = optarg;
1799 				ifl->ifl_flags = (FLG_IF_NEEDSTR |
1800 				    FLG_IF_FILEREF | FLG_IF_DEPREQD);
1801 
1802 				break;
1803 			case 'D':
1804 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1805 				    optarg));
1806 				(void) dbg_setup(ofl, optarg, 3);
1807 				break;
1808 			case 'u':
1809 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1810 				    optarg));
1811 				if (ld_sym_add_u(optarg, ofl,
1812 				    MSG_STR_COMMAND) == (Sym_desc *)S_ERROR)
1813 					return (S_ERROR);
1814 				break;
1815 			case 'z':
1816 				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1817 				    optarg));
1818 				if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1819 				    MSG_ARG_LD32_SIZE) == 0) ||
1820 				    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1821 				    MSG_ARG_LD64_SIZE) == 0)) {
1822 					if (createargv(ofl, 0) == S_ERROR)
1823 						return (S_ERROR);
1824 				} else if (strcmp(optarg,
1825 				    MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1826 					ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1827 					ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1828 				} else if (strcmp(optarg,
1829 				    MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1830 					ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1831 					ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1832 				} else if (strcmp(optarg,
1833 				    MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1834 					ofl->ofl_flags1 &=
1835 					    ~(FLG_OF1_ALLEXRT |
1836 					    FLG_OF1_WEAKEXT);
1837 				} else if (strcmp(optarg,
1838 				    MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1839 					ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1840 					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1841 				} else if (strcmp(optarg,
1842 				    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1843 					ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1844 					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1845 				} else if (strcmp(optarg,
1846 				    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1847 					ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1848 				} else if (strcmp(optarg,
1849 				    MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1850 					ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1851 				} else if (strcmp(optarg,
1852 				    MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1853 					ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1854 					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1855 				} else if (strcmp(optarg,
1856 				    MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1857 					ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1858 					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1859 				} else if (strcmp(optarg,
1860 				    MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1861 					ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1862 				} else if (strcmp(optarg,
1863 				    MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1864 					ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1865 				} else if (strncmp(optarg,
1866 				    MSG_ORIG(MSG_ARG_INITARRAY),
1867 				    MSG_ARG_INITARRAY_SIZE) == 0) {
1868 					if (((sdp = ld_sym_add_u(optarg +
1869 					    MSG_ARG_INITARRAY_SIZE, ofl,
1870 					    MSG_STR_COMMAND)) ==
1871 					    (Sym_desc *)S_ERROR) ||
1872 					    (aplist_append(&ofl->ofl_initarray,
1873 					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1874 						return (S_ERROR);
1875 				} else if (strncmp(optarg,
1876 				    MSG_ORIG(MSG_ARG_FINIARRAY),
1877 				    MSG_ARG_FINIARRAY_SIZE) == 0) {
1878 					if (((sdp = ld_sym_add_u(optarg +
1879 					    MSG_ARG_FINIARRAY_SIZE, ofl,
1880 					    MSG_STR_COMMAND)) ==
1881 					    (Sym_desc *)S_ERROR) ||
1882 					    (aplist_append(&ofl->ofl_finiarray,
1883 					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1884 						return (S_ERROR);
1885 				} else if (strncmp(optarg,
1886 				    MSG_ORIG(MSG_ARG_PREINITARRAY),
1887 				    MSG_ARG_PREINITARRAY_SIZE) == 0) {
1888 					if (((sdp = ld_sym_add_u(optarg +
1889 					    MSG_ARG_PREINITARRAY_SIZE, ofl,
1890 					    MSG_STR_COMMAND)) ==
1891 					    (Sym_desc *)S_ERROR) ||
1892 					    (aplist_append(&ofl->ofl_preiarray,
1893 					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1894 						return (S_ERROR);
1895 				} else if (strncmp(optarg,
1896 				    MSG_ORIG(MSG_ARG_RTLDINFO),
1897 				    MSG_ARG_RTLDINFO_SIZE) == 0) {
1898 					if (((sdp = ld_sym_add_u(optarg +
1899 					    MSG_ARG_RTLDINFO_SIZE, ofl,
1900 					    MSG_STR_COMMAND)) ==
1901 					    (Sym_desc *)S_ERROR) ||
1902 					    (aplist_append(&ofl->ofl_rtldinfo,
1903 					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1904 						return (S_ERROR);
1905 				} else if (strncmp(optarg,
1906 				    MSG_ORIG(MSG_ARG_DTRACE),
1907 				    MSG_ARG_DTRACE_SIZE) == 0) {
1908 					if ((sdp = ld_sym_add_u(optarg +
1909 					    MSG_ARG_DTRACE_SIZE, ofl,
1910 					    MSG_STR_COMMAND)) ==
1911 					    (Sym_desc *)S_ERROR)
1912 						return (S_ERROR);
1913 					ofl->ofl_dtracesym = sdp;
1914 				} else if (strcmp(optarg,
1915 				    MSG_ORIG(MSG_ARG_RESCAN_NOW)) == 0) {
1916 					if (ld_rescan_archives(ofl, 0, ndx) ==
1917 					    S_ERROR)
1918 						return (S_ERROR);
1919 				} else if (strcmp(optarg,
1920 				    MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1921 					ofl->ofl_ars_gsndx = ofl->ofl_arscnt;
1922 					ofl->ofl_ars_gsandx = ndx;
1923 				} else if (strcmp(optarg,
1924 				    MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1925 					if (ld_rescan_archives(ofl, 1, ndx) ==
1926 					    S_ERROR)
1927 						return (S_ERROR);
1928 				} else if (strcmp(optarg,
1929 				    MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
1930 					ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
1931 				} else if (strcmp(optarg,
1932 				    MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
1933 					ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
1934 				}
1935 			default:
1936 				break;
1937 		}
1938 
1939 		/*
1940 		 * Update the argument index for the next getopt() iteration.
1941 		 */
1942 		ndx = optind;
1943 	}
1944 	return (1);
1945 }
1946 
1947 /*
1948  *
1949  * Pass 1 -- process_flags: collects all options and sets flags
1950  */
1951 static uintptr_t
1952 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
1953 {
1954 	for (; optind < argc; optind++) {
1955 		/*
1956 		 * If we detect some more options return to getopt().
1957 		 * Checking argv[optind][1] against null prevents a forever
1958 		 * loop if an unadorned `-' argument is passed to us.
1959 		 */
1960 		while ((optind < argc) && (argv[optind][0] == '-')) {
1961 			if (argv[optind][1] != '\0') {
1962 				if (parseopt_pass1(ofl, argc, argv,
1963 				    usage) == S_ERROR)
1964 					return (S_ERROR);
1965 			} else if (++optind < argc)
1966 				continue;
1967 		}
1968 		if (optind >= argc)
1969 			break;
1970 		ofl->ofl_objscnt++;
1971 	}
1972 
1973 	/* Did an unterminated archive group run off the end? */
1974 	if (ofl->ofl_ars_gsandx > 0) {
1975 		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
1976 		    MSG_INTL(MSG_MARG_AR_GRP_START),
1977 		    MSG_INTL(MSG_MARG_AR_GRP_END));
1978 		return (S_ERROR);
1979 	}
1980 
1981 	return (1);
1982 }
1983 
1984 uintptr_t
1985 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
1986 {
1987 	int	usage = 0;	/* Collect all argument errors before exit */
1988 
1989 	if (argc < 2) {
1990 		usage_mesg(FALSE);
1991 		return (S_ERROR);
1992 	}
1993 
1994 	/*
1995 	 * Option handling
1996 	 */
1997 	opterr = 0;
1998 	optind = 1;
1999 	if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
2000 		return (S_ERROR);
2001 
2002 	/*
2003 	 * Having parsed everything, did we have any usage errors.
2004 	 */
2005 	if (usage) {
2006 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
2007 		return (S_ERROR);
2008 	}
2009 
2010 	return (check_flags(ofl, argc));
2011 }
2012 
2013 /*
2014  * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
2015  * files.
2016  */
2017 static uintptr_t
2018 process_files_com(Ofl_desc *ofl, int argc, char **argv)
2019 {
2020 	for (; optind < argc; optind++) {
2021 		int		fd;
2022 		uintptr_t	open_ret;
2023 		char		*path;
2024 		Rej_desc	rej = { 0 };
2025 
2026 		/*
2027 		 * If we detect some more options return to getopt().
2028 		 * Checking argv[optind][1] against null prevents a forever
2029 		 * loop if an unadorned `-' argument is passed to us.
2030 		 */
2031 		while ((optind < argc) && (argv[optind][0] == '-')) {
2032 			if (argv[optind][1] != '\0') {
2033 				if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
2034 					return (S_ERROR);
2035 			} else if (++optind < argc)
2036 				continue;
2037 		}
2038 		if (optind >= argc)
2039 			break;
2040 
2041 		path = argv[optind];
2042 		if ((fd = open(path, O_RDONLY)) == -1) {
2043 			int err = errno;
2044 
2045 			ld_eprintf(ofl, ERR_FATAL,
2046 			    MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
2047 			continue;
2048 		}
2049 
2050 		DBG_CALL(Dbg_args_file(ofl->ofl_lml, optind, path));
2051 
2052 		open_ret = ld_process_open(path, path, &fd, ofl,
2053 		    (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej, NULL);
2054 		if (fd != -1)
2055 			(void) close(fd);
2056 		if (open_ret == S_ERROR)
2057 			return (S_ERROR);
2058 
2059 		/*
2060 		 * Check for mismatched input.
2061 		 */
2062 		if (rej.rej_type) {
2063 			Conv_reject_desc_buf_t rej_buf;
2064 
2065 			ld_eprintf(ofl, ERR_FATAL,
2066 			    MSG_INTL(reject[rej.rej_type]),
2067 			    rej.rej_name ? rej.rej_name :
2068 			    MSG_INTL(MSG_STR_UNKNOWN),
2069 			    conv_reject_desc(&rej, &rej_buf,
2070 			    ld_targ.t_m.m_mach));
2071 			return (1);
2072 		}
2073 	}
2074 	return (1);
2075 }
2076 
2077 uintptr_t
2078 ld_process_files(Ofl_desc *ofl, int argc, char **argv)
2079 {
2080 	DBG_CALL(Dbg_basic_files(ofl->ofl_lml));
2081 
2082 	/*
2083 	 * Process command line files (taking into account any applicable
2084 	 * preceding flags).  Return if any fatal errors have occurred.
2085 	 */
2086 	opterr = 0;
2087 	optind = 1;
2088 	if (process_files_com(ofl, argc, argv) == S_ERROR)
2089 		return (S_ERROR);
2090 	if (ofl->ofl_flags & FLG_OF_FATAL)
2091 		return (1);
2092 
2093 	/*
2094 	 * Guidance: Use -B direct/nodirect or -z direct/nodirect.
2095 	 *
2096 	 * This is a backstop for the case where the link had no dependencies.
2097 	 * Otherwise, it will get caught by ld_process_ifl(). We need both,
2098 	 * because -z direct is positional, and its value at the time where
2099 	 * the first dependency is seen might be different than it is now.
2100 	 */
2101 	if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
2102 	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
2103 		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
2104 		ofl->ofl_guideflags |= FLG_OFG_NO_DB;
2105 	}
2106 
2107 	/*
2108 	 * Now that all command line files have been processed see if there are
2109 	 * any additional `needed' shared object dependencies.
2110 	 */
2111 	if (ofl->ofl_soneed)
2112 		if (ld_finish_libs(ofl) == S_ERROR)
2113 			return (S_ERROR);
2114 
2115 	/*
2116 	 * If rescanning archives is enabled, do so now to determine whether
2117 	 * there might still be members extracted to satisfy references from any
2118 	 * explicit objects.  Continue until no new objects are extracted.  Note
2119 	 * that this pass is carried out *after* processing any implicit objects
2120 	 * (above) as they may already have resolved any undefined references
2121 	 * from any explicit dependencies.
2122 	 */
2123 	if (ofl->ofl_flags1 & FLG_OF1_RESCAN) {
2124 		if (ld_rescan_archives(ofl, 0, argc) == S_ERROR)
2125 			return (S_ERROR);
2126 		if (ofl->ofl_flags & FLG_OF_FATAL)
2127 			return (1);
2128 	}
2129 
2130 	/*
2131 	 * If debugging, provide statistics on each archives extraction, or flag
2132 	 * any archive that has provided no members.  Note that this could be a
2133 	 * nice place to free up much of the archive infrastructure, as we've
2134 	 * extracted any members we need.  However, as we presently don't free
2135 	 * anything under ld(1) there's not much point in proceeding further.
2136 	 */
2137 	DBG_CALL(Dbg_statistics_ar(ofl));
2138 
2139 	/*
2140 	 * If any version definitions have been established, either via input
2141 	 * from a mapfile or from the input relocatable objects, make sure any
2142 	 * version dependencies are satisfied, and version symbols created.
2143 	 */
2144 	if (ofl->ofl_verdesc)
2145 		if (ld_vers_check_defs(ofl) == S_ERROR)
2146 			return (S_ERROR);
2147 
2148 	/*
2149 	 * If input section ordering was specified within some segment
2150 	 * using a mapfile, verify that the expected sections were seen.
2151 	 */
2152 	if (ofl->ofl_flags & FLG_OF_IS_ORDER)
2153 		ld_ent_check(ofl);
2154 
2155 	return (1);
2156 }
2157 
2158 uintptr_t
2159 ld_init_strings(Ofl_desc *ofl)
2160 {
2161 	uint_t	stflags;
2162 
2163 	if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
2164 		stflags = 0;
2165 	else
2166 		stflags = FLG_STNEW_COMPRESS;
2167 
2168 	if (((ofl->ofl_shdrsttab = st_new(stflags)) == NULL) ||
2169 	    ((ofl->ofl_strtab = st_new(stflags)) == NULL) ||
2170 	    ((ofl->ofl_dynstrtab = st_new(stflags)) == NULL))
2171 		return (S_ERROR);
2172 
2173 	return (0);
2174 }
2175