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