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