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