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