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