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