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