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