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