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