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