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