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