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