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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
27 */
28/*
29 * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
30 * Copyright 2017 RackTop Systems.
31 */
32
33/*
34 * Publicly available flags are defined in ld(1).   The following flags are
35 * private, and may be removed at any time.
36 *
37 *    OPTION			MEANING
38 *
39 *    -z dtrace=symbol		assigns symbol to PT_SUNWDTRACE segment,
40 *				providing scratch area for dtrace processing.
41 *
42 *    -z noreloc		suppress relocation processing.  This provides
43 *				a mechanism for validating kernel module symbol
44 *				resolution that would normally incur fatal
45 *				relocation errors.
46 *
47 *    -z rtldinfo=symbol	assigns symbol to SUNW_RTLDINF dynamic tag,
48 *				providing pre-initialization specific routines
49 *				for TLS initialization.
50 *
51 *    -z nointerp		suppress the addition of an interpreter
52 *				section.  This is used to generate the kernel,
53 *				but makes no sense to be used by anyone else.
54 *
55 *    -z norelaxreloc		suppress the automatic addition of relaxed
56 *				relocations to GNU linkonce/COMDAT sections.
57 *
58 *    -z nosighandler		suppress the registration of the signal handler
59 *				used to manage SIGBUS.
60 */
61
62/*
63 * The following flags are committed, and will not be removed, but are
64 * not publically documented, either because they are obsolete, or because
65 * they exist to work around defects in other software and are not of
66 * sufficient interest otherwise.
67 *
68 *    OPTION			MEANING
69 *
70 *    -Wl,...			compiler drivers and configuration tools
71 *				have been known to pass this compiler option
72 *				to ld(1).  Strip off the "-Wl," prefix and
73 *			        process the remainder (...) as a normal option.
74 */
75
76#include	<sys/link.h>
77#include	<stdio.h>
78#include	<fcntl.h>
79#include	<string.h>
80#include	<errno.h>
81#include	<elf.h>
82#include	<unistd.h>
83#include	<debug.h>
84#include	"msg.h"
85#include	"_libld.h"
86
87/*
88 * Define a set of local argument flags, the settings of these will be
89 * verified in check_flags() and lead to the appropriate output file flags
90 * being initialized.
91 */
92typedef	enum {
93	SET_UNKNOWN = -1,
94	SET_FALSE = 0,
95	SET_TRUE = 1
96} Setstate;
97
98static Setstate	dflag	= SET_UNKNOWN;
99static Setstate	zdflag	= SET_UNKNOWN;
100static Setstate	Qflag	= SET_UNKNOWN;
101static Setstate	Bdflag	= SET_UNKNOWN;
102static Setstate zfwflag	= SET_UNKNOWN;
103
104static Boolean	aflag	= FALSE;
105static Boolean	bflag	= FALSE;
106static Boolean	sflag	= FALSE;
107static Boolean	zinflag = FALSE;
108static Boolean	zlflag	= FALSE;
109static Boolean	Bgflag	= FALSE;
110static Boolean	Blflag	= FALSE;
111static Boolean	Beflag	= FALSE;
112static Boolean	Bsflag	= FALSE;
113static Boolean	Dflag	= FALSE;
114static Boolean	Vflag	= FALSE;
115
116enum output_type {
117	OT_RELOC,		/* relocatable object */
118	OT_SHARED,		/* shared object */
119	OT_EXEC,		/* dynamic executable */
120	OT_KMOD,		/* kernel module */
121};
122
123static enum output_type	otype = OT_EXEC;
124
125/*
126 * ztflag's state is set by pointing it to the matching string:
127 *	text | textoff | textwarn
128 */
129static const char	*ztflag = NULL;
130
131/*
132 * Remember the guidance flags that result from the initial -z guidance
133 * option, so that they can be compared to any that follow. We only want
134 * to issue a warning when they differ.
135 */
136static ofl_guideflag_t	initial_guidance_flags	= 0;
137
138static uintptr_t process_files_com(Ofl_desc *, int, char **);
139static uintptr_t process_flags_com(Ofl_desc *, int, char **, int *);
140
141/*
142 * Print usage message to stderr - 2 modes, summary message only,
143 * and full usage message.
144 */
145static void
146usage_mesg(Boolean detail)
147{
148	(void) fprintf(stderr, MSG_INTL(MSG_ARG_USAGE),
149	    MSG_ORIG(MSG_STR_OPTIONS));
150
151	if (detail == FALSE)
152		return;
153
154	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_3));
155	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_6));
156	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_A));
157	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_B));
158	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDR));
159	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDY));
160	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBE));
161	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBG));
162	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBL));
163	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBR));
164	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBS));
165	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_C));
166	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CC));
167	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_D));
168	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CD));
169	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_E));
170	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_F));
171	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CF));
172	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CG));
173	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_H));
174	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_I));
175	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CI));
176	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_L));
177	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CL));
178	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_M));
179	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CM));
180	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CN));
181	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_O));
182	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_P));
183	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CP));
184	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CQ));
185	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_R));
186	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CR));
187	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_S));
188	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CS));
189	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_T));
190	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_U));
191	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CV));
192	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY));
193	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA));
194	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
195	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL));
196	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZADLIB));
197	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
198	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDEF));
199	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
200	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
201	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
202	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFATW));
203	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFA));
204	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGP));
205	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGUIDE));
206	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZH));
207	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZIG));
208	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINA));
209	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINI));
210	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINT));
211	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLAZY));
212	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD32));
213	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD64));
214	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLO));
215	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZM));
216	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNC));
217	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDFS));
218	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEF));
219	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEL));
220	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDLO));
221	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDU));
222	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNLD));
223	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNOW));
224	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNPA));
225	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNV));
226	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZO));
227	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZPIA));
228	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRL));
229	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRREL));
230	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRS));
231	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSN));
232	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSGRP));
233	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZSCAP));
234	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTARG));
235	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT));
236	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO));
237	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW));
238	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTY));
239	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZWRAP));
240	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZVER));
241}
242
243/*
244 * Rescan the archives seen on the command line in order
245 * to handle circularly dependent archives, stopping when
246 * no further member extraction occurs.
247 *
248 * entry:
249 *	ofl - Output file descriptor
250 *	isgrp - True if this is a an archive group search, False
251 *		to search starting with argv[1] through end_arg_ndx
252 *	end_arg_ndx - Index of final argv element to consider.
253 */
254static uintptr_t
255ld_rescan_archives(Ofl_desc *ofl, int isgrp, int end_arg_ndx)
256{
257	ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
258
259	while (ofl->ofl_flags1 & FLG_OF1_EXTRACT) {
260		Aliste		idx;
261		Ar_desc		*adp;
262		Word		start_ndx = isgrp ? ofl->ofl_ars_gsndx : 0;
263		Word		ndx = 0;
264
265		ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT;
266
267		DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml,
268		    isgrp ? ofl->ofl_ars_gsandx : 1, end_arg_ndx));
269
270		for (APLIST_TRAVERSE(ofl->ofl_ars, idx, adp)) {
271			/* If not to starting index yet, skip it */
272			if (ndx++ < start_ndx)
273				continue;
274
275			/*
276			 * If this archive was processed with -z allextract,
277			 * then all members have already been extracted.
278			 */
279			if (adp->ad_elf == NULL)
280				continue;
281
282			/*
283			 * Reestablish any archive specific command line flags.
284			 */
285			ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE;
286			ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE);
287
288			/*
289			 * Re-process the archive.  Note that a file descriptor
290			 * is unnecessary, as the file is already available in
291			 * memory.
292			 */
293			if (!ld_process_archive(adp->ad_name, -1, adp, ofl))
294				return (S_ERROR);
295			if (ofl->ofl_flags & FLG_OF_FATAL)
296				return (1);
297		}
298	}
299
300	return (1);
301}
302
303/*
304 * Checks the command line option flags for consistency.
305 */
306static uintptr_t
307check_flags(Ofl_desc * ofl, int argc)
308{
309	/*
310	 * If the user specified -zguidance=noall, then we can safely disable
311	 * the entire feature. The purpose of -zguidance=noall is to allow
312	 * the user to override guidance specified from a makefile via
313	 * the LD_OPTIONS environment variable, and so, we want to behave
314	 * in exactly the same manner we would have if no option were present.
315	 */
316	if ((ofl->ofl_guideflags & (FLG_OFG_ENABLE | FLG_OFG_NO_ALL)) ==
317	    (FLG_OFG_ENABLE | FLG_OFG_NO_ALL))
318		ofl->ofl_guideflags &= ~FLG_OFG_ENABLE;
319
320	if (Plibpath && (Llibdir || Ulibdir))
321		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
322		    Llibdir ? 'L' : 'U');
323
324	if ((otype == OT_RELOC) || (otype == OT_KMOD)) {
325		if (otype == OT_RELOC) {
326			if (dflag == SET_UNKNOWN)
327				dflag = SET_FALSE;
328			if ((dflag == SET_TRUE) &&
329			    OFL_GUIDANCE(ofl, FLG_OFG_NO_KMOD)) {
330				ld_eprintf(ofl, ERR_GUIDANCE,
331				    MSG_INTL(MSG_GUIDE_KMOD));
332			}
333		} else if (otype == OT_KMOD) {
334			if (dflag != SET_UNKNOWN) {
335				ld_eprintf(ofl, ERR_FATAL,
336				    MSG_INTL(MSG_MARG_INCOMP),
337				    MSG_INTL(MSG_MARG_TYPE_KMOD),
338				    MSG_ORIG(MSG_ARG_D));
339			}
340
341			dflag = SET_TRUE;
342		}
343
344		/*
345		 * Combining relocations when building a relocatable
346		 * object isn't allowed.  Warn the user, but proceed.
347		 */
348		if (ofl->ofl_flags & FLG_OF_COMREL) {
349			const char *msg;
350
351			if (otype == OT_RELOC) {
352				msg = MSG_INTL(MSG_MARG_REL);
353			} else {
354				msg = MSG_INTL(MSG_MARG_TYPE_KMOD);
355			}
356			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP),
357			    msg,
358			    MSG_ORIG(MSG_ARG_ZCOMBRELOC));
359		}
360		ofl->ofl_flags |= FLG_OF_RELOBJ;
361
362		if (otype == OT_KMOD)
363			ofl->ofl_flags |= FLG_OF_KMOD;
364	} else {
365		/*
366		 * Translating object capabilities to symbol capabilities is
367		 * only meaningful when creating a relocatable object.
368		 */
369		if (ofl->ofl_flags & FLG_OF_OTOSCAP)
370			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ONLY),
371			    MSG_ORIG(MSG_ARG_ZSYMBOLCAP),
372			    MSG_INTL(MSG_MARG_REL));
373
374		/*
375		 * If the user hasn't explicitly requested that relocations
376		 * not be combined, combine them by default.
377		 */
378		if ((ofl->ofl_flags & FLG_OF_NOCOMREL) == 0)
379			ofl->ofl_flags |= FLG_OF_COMREL;
380	}
381
382	if (zdflag == SET_TRUE)
383		ofl->ofl_flags |= FLG_OF_NOUNDEF;
384
385	if (zinflag)
386		ofl->ofl_dtflags_1 |= DF_1_INTERPOSE;
387
388	if (sflag)
389		ofl->ofl_flags |= FLG_OF_STRIP;
390
391	if (Qflag == SET_TRUE)
392		ofl->ofl_flags |= FLG_OF_ADDVERS;
393
394	if (Blflag)
395		ofl->ofl_flags |= FLG_OF_AUTOLCL;
396
397	if (Beflag)
398		ofl->ofl_flags |= FLG_OF_AUTOELM;
399
400	if (Blflag && Beflag)
401		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
402		    MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL));
403
404	if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP))
405		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
406		    MSG_ORIG(MSG_ARG_CI), MSG_ORIG(MSG_ARG_ZNOINTERP));
407
408	if ((ofl->ofl_flags1 & (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ==
409	    (FLG_OF1_NRLXREL | FLG_OF1_RLXREL))
410		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
411		    MSG_ORIG(MSG_ARG_ZRELAXRELOC),
412		    MSG_ORIG(MSG_ARG_ZNORELAXRELOC));
413
414	if (ofl->ofl_filtees && (otype != OT_SHARED))
415		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL),
416		    ((ofl->ofl_flags & FLG_OF_AUX) ?
417		    MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER)));
418
419	if (dflag != SET_FALSE) {
420		/*
421		 * Set -Bdynamic on by default, setting is rechecked as input
422		 * files are processed.
423		 */
424		ofl->ofl_flags |=
425		    (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED);
426
427		if (aflag)
428			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
429			    MSG_ORIG(MSG_ARG_DY), MSG_ORIG(MSG_ARG_A));
430
431		if (bflag)
432			ofl->ofl_flags |= FLG_OF_BFLAG;
433
434		if (Bgflag == TRUE) {
435			if (zdflag == SET_FALSE)
436				ld_eprintf(ofl, ERR_FATAL,
437				    MSG_INTL(MSG_ARG_INCOMP),
438				    MSG_ORIG(MSG_ARG_BGROUP),
439				    MSG_ORIG(MSG_ARG_ZNODEF));
440			ofl->ofl_dtflags_1 |= DF_1_GROUP;
441			ofl->ofl_flags |= FLG_OF_NOUNDEF;
442		}
443
444		/*
445		 * If the use of default library searching has been suppressed
446		 * but no runpaths have been provided we're going to have a hard
447		 * job running this object.
448		 */
449		if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath)
450			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ARG_NODEFLIB),
451			    MSG_INTL(MSG_MARG_RPATH));
452
453		/*
454		 * By default, text relocation warnings are given when building
455		 * an executable unless the -b flag is specified.  This option
456		 * implies that unclean text can be created, so no warnings are
457		 * generated unless specifically asked for.
458		 */
459		if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) ||
460		    ((ztflag == NULL) && bflag)) {
461			ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
462			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
463		} else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) {
464			ofl->ofl_flags |= FLG_OF_PURETXT;
465			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
466		}
467
468		if ((otype == OT_SHARED) || (otype == OT_EXEC)) {
469			/*
470			 * Create a dynamic object.  -Bdirect indicates that all
471			 * references should be bound directly.  This also
472			 * enables lazyloading.  Individual symbols can be
473			 * bound directly (or not) using mapfiles and the
474			 * DIRECT (NODIRECT) qualifier.  With this capability,
475			 * each syminfo entry is tagged SYMINFO_FLG_DIRECTBIND.
476			 * Prior to this per-symbol direct binding, runtime
477			 * direct binding was controlled via the DF_1_DIRECT
478			 * flag.  This flag affected all references from the
479			 * object.  -Bdirect continues to set this flag, and
480			 * thus provides a means of taking a newly built
481			 * direct binding object back to older systems.
482			 *
483			 * NOTE, any use of per-symbol NODIRECT bindings, or
484			 * -znodirect, will disable the creation of the
485			 * DF_1_DIRECT flag.  Older runtime linkers do not
486			 * have the capability to do per-symbol direct bindings.
487			 */
488			if (Bdflag == SET_TRUE) {
489				ofl->ofl_dtflags_1 |= DF_1_DIRECT;
490				ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
491				ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
492				ofl->ofl_flags |= FLG_OF_SYMINFO;
493			}
494
495			/*
496			 * -Bnodirect disables directly binding to any symbols
497			 * exported from the object being created.  Individual
498			 * references to external objects can still be affected
499			 * by -zdirect or mapfile DIRECT directives.
500			 */
501			if (Bdflag == SET_FALSE) {
502				ofl->ofl_flags1 |= (FLG_OF1_NDIRECT |
503				    FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR);
504				ofl->ofl_flags |= FLG_OF_SYMINFO;
505			}
506		}
507
508		if (otype == OT_EXEC) {
509			/*
510			 * Dynamically linked executable.
511			 */
512			ofl->ofl_flags |= FLG_OF_EXEC;
513
514			if (zdflag != SET_FALSE)
515				ofl->ofl_flags |= FLG_OF_NOUNDEF;
516
517			/*
518			 * -z textwarn is the default for executables, and
519			 * only an explicit -z text* option can change that,
520			 * so there's no need to provide additional guidance.
521			 */
522			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
523
524			if (Bsflag)
525				ld_eprintf(ofl, ERR_FATAL,
526				    MSG_INTL(MSG_ARG_DY_INCOMP),
527				    MSG_ORIG(MSG_ARG_BSYMBOLIC));
528			if (ofl->ofl_soname)
529				ld_eprintf(ofl, ERR_FATAL,
530				    MSG_INTL(MSG_MARG_DY_INCOMP),
531				    MSG_INTL(MSG_MARG_SONAME));
532		} else if (otype == OT_SHARED) {
533			/*
534			 * Shared library.
535			 */
536			ofl->ofl_flags |= FLG_OF_SHAROBJ;
537
538			/*
539			 * By default, print text relocation warnings for
540			 * executables but *not* for shared objects. However,
541			 * if -z guidance is on, issue warnings for shared
542			 * objects as well.
543			 *
544			 * If -z textwarn is explicitly specified, also issue
545			 * guidance messages if -z guidance is on, but not
546			 * for -z text or -z textoff.
547			 */
548			if (ztflag == NULL) {
549				if (!OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
550					ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
551			} else if ((ofl->ofl_flags & FLG_OF_PURETXT) ||
552			    (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)) {
553				ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
554			}
555
556			if (Bsflag) {
557				/*
558				 * -Bsymbolic, and -Bnodirect make no sense.
559				 */
560				if (Bdflag == SET_FALSE)
561					ld_eprintf(ofl, ERR_FATAL,
562					    MSG_INTL(MSG_ARG_INCOMP),
563					    MSG_ORIG(MSG_ARG_BSYMBOLIC),
564					    MSG_ORIG(MSG_ARG_BNODIRECT));
565				ofl->ofl_flags |= FLG_OF_SYMBOLIC;
566				ofl->ofl_dtflags |= DF_SYMBOLIC;
567			}
568		} else {
569			/*
570			 * Dynamic relocatable object.
571			 */
572			if (ztflag == NULL)
573				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
574			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
575
576			if (ofl->ofl_interp)
577				ld_eprintf(ofl, ERR_FATAL,
578				    MSG_INTL(MSG_MARG_INCOMP),
579				    MSG_INTL(MSG_MARG_REL),
580				    MSG_ORIG(MSG_ARG_CI));
581		}
582
583		assert((ofl->ofl_flags & (FLG_OF_SHAROBJ|FLG_OF_EXEC)) !=
584		    (FLG_OF_SHAROBJ|FLG_OF_EXEC));
585	} else {
586		ofl->ofl_flags |= FLG_OF_STATIC;
587
588		if (bflag)
589			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
590			    MSG_ORIG(MSG_ARG_B));
591		if (ofl->ofl_soname)
592			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
593			    MSG_INTL(MSG_MARG_SONAME));
594		if (ofl->ofl_depaudit)
595			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
596			    MSG_ORIG(MSG_ARG_CP));
597		if (ofl->ofl_audit)
598			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
599			    MSG_ORIG(MSG_ARG_P));
600		if (ofl->ofl_config)
601			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
602			    MSG_ORIG(MSG_ARG_C));
603		if (ztflag)
604			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
605			    MSG_ORIG(MSG_ARG_ZTEXTALL));
606		if (otype == OT_SHARED)
607			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
608			    MSG_INTL(MSG_MARG_SO));
609		if (aflag && (otype == OT_RELOC))
610			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP),
611			    MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL));
612
613		if (otype == OT_RELOC) {
614			/*
615			 * We can only strip the symbol table and string table
616			 * if no output relocations will refer to them.
617			 */
618			if (sflag)
619				ld_eprintf(ofl, ERR_WARNING,
620				    MSG_INTL(MSG_ARG_STRIP),
621				    MSG_INTL(MSG_MARG_REL),
622				    MSG_INTL(MSG_MARG_STRIP));
623
624			if (ztflag == NULL)
625				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
626			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
627
628			if (ofl->ofl_interp)
629				ld_eprintf(ofl, ERR_FATAL,
630				    MSG_INTL(MSG_MARG_INCOMP),
631				    MSG_INTL(MSG_MARG_REL),
632				    MSG_ORIG(MSG_ARG_CI));
633		} else {
634			/*
635			 * Static executable.
636			 */
637			ofl->ofl_flags |= FLG_OF_EXEC | FLG_OF_PROCRED;
638
639			if (zdflag != SET_FALSE)
640				ofl->ofl_flags |= FLG_OF_NOUNDEF;
641		}
642	}
643
644	/*
645	 * If the user didn't supply an output file name supply a default.
646	 */
647	if (ofl->ofl_name == NULL)
648		ofl->ofl_name = MSG_ORIG(MSG_STR_AOUT);
649
650	/*
651	 * We set the entrance criteria after all input argument processing as
652	 * it is only at this point we're sure what the output image will be
653	 * (static or dynamic).
654	 */
655	if (ld_ent_setup(ofl, ld_targ.t_m.m_segm_align) == S_ERROR)
656		return (S_ERROR);
657
658	/*
659	 * Does the host currently running the linker have the same
660	 * byte order as the target for which the object is being produced?
661	 * If not, set FLG_OF1_ENCDIFF so relocation code will know
662	 * to check.
663	 */
664	if (_elf_sys_encoding() != ld_targ.t_m.m_data)
665		ofl->ofl_flags1 |= FLG_OF1_ENCDIFF;
666
667	/*
668	 * If the target has special executable section filling requirements,
669	 * register the fill function with libelf
670	 */
671	if (ld_targ.t_ff.ff_execfill != NULL)
672		_elf_execfill(ld_targ.t_ff.ff_execfill);
673
674	/*
675	 * Initialize string tables.  Symbol definitions within mapfiles can
676	 * result in the creation of input sections.
677	 */
678	if (ld_init_strings(ofl) == S_ERROR)
679		return (S_ERROR);
680
681	/*
682	 * Process mapfiles. Mapfile can redefine or add sections/segments,
683	 * so this must come after the default entrance criteria are established
684	 * (above).
685	 */
686	if (ofl->ofl_maps) {
687		const char	*name;
688		Aliste		idx;
689
690		for (APLIST_TRAVERSE(ofl->ofl_maps, idx, name))
691			if (!ld_map_parse(name, ofl))
692				return (S_ERROR);
693
694		if (!ld_map_post_process(ofl))
695			return (S_ERROR);
696	}
697
698	/*
699	 * If a mapfile has been used to define a single symbolic scope of
700	 * interfaces, -Bsymbolic is established.  This global setting goes
701	 * beyond individual symbol protection, and ensures all relocations
702	 * (even those that reference section symbols) are processed within
703	 * the object being built.
704	 */
705	if (((ofl->ofl_flags &
706	    (FLG_OF_MAPSYMB | FLG_OF_MAPGLOB)) == FLG_OF_MAPSYMB) &&
707	    (ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM))) {
708		ofl->ofl_flags |= FLG_OF_SYMBOLIC;
709		ofl->ofl_dtflags |= DF_SYMBOLIC;
710	}
711
712	/*
713	 * If -zloadfltr is set, verify that filtering is in effect.  Filters
714	 * are either established from the command line, and affect the whole
715	 * object, or are set on a per-symbol basis from a mapfile.
716	 */
717	if (zlflag) {
718		if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL))
719			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFLTR),
720			    MSG_ORIG(MSG_ARG_ZLOADFLTR));
721		ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
722	}
723
724	/*
725	 * Check that we have something to work with. This check is carried out
726	 * after mapfile processing as its possible a mapfile is being used to
727	 * define symbols, in which case it would be sufficient to build the
728	 * output file purely from the mapfile.
729	 */
730	if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
731		if ((Vflag ||
732		    (Dflag && (dbg_desc->d_extra & DBG_E_HELP_EXIT))) &&
733		    (argc == 2)) {
734			ofl->ofl_flags1 |= FLG_OF1_DONE;
735		} else {
736			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFILES));
737			return (S_ERROR);
738		}
739	}
740	return (1);
741}
742
743/*
744 * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
745 * used as an argument to getopt().
746 *
747 * If the second argument 'usage' is not NULL, then this is called from the
748 * first pass. Else this is called from the second pass.
749 */
750static uintptr_t
751createargv(Ofl_desc *ofl, int *usage)
752{
753	int		argc = 0, idx = 0, ooptind;
754	uintptr_t	ret;
755	char		**argv, *p0;
756
757	/*
758	 * The argument being examined is either:
759	 *	ld32=	or
760	 *	ld64=
761	 */
762#if	defined(_LP64)
763	if (optarg[2] == '3')
764		return (0);
765#else
766	if (optarg[2] == '6')
767		return (0);
768#endif
769
770	p0 = &optarg[5];
771
772	/*
773	 * Count the number of arguments.
774	 */
775	while (*p0) {
776		/*
777		 * Pointing at non-separator character.
778		 */
779		if (*p0 != ',') {
780			argc++;
781			while (*p0 && (*p0 != ','))
782				p0++;
783			continue;
784		}
785
786		/*
787		 * Pointing at a separator character.
788		 */
789		if (*p0 == ',') {
790			while (*p0 == ',')
791				p0++;
792			continue;
793		}
794	}
795
796	if (argc == 0)
797		return (0);
798
799	/*
800	 * Allocate argument vector.
801	 */
802	if ((p0 = (char *)strdup(&optarg[5])) == NULL)
803		return (S_ERROR);
804	if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == NULL)
805		return (S_ERROR);
806
807	while (*p0) {
808		char *p;
809
810		/*
811		 * Pointing at the beginning of non-separator character string.
812		 */
813		if (*p0 != ',') {
814			p = p0;
815			while (*p0 && (*p0 != ','))
816				p0++;
817			argv[idx++] = p;
818			if (*p0) {
819				*p0 = '\0';
820				p0++;
821			}
822			continue;
823		}
824
825		/*
826		 * Pointing at the beginining of separator character string.
827		 */
828		if (*p0 == ',') {
829			while (*p0 == ',')
830				p0++;
831			continue;
832		}
833	}
834	argv[idx] = 0;
835	ooptind = optind;
836	optind = 0;
837
838	/*
839	 * Dispatch to pass1 or pass2
840	 */
841	if (usage)
842		ret = process_flags_com(ofl, argc, argv, usage);
843	else
844		ret = process_files_com(ofl, argc, argv);
845
846	optind = ooptind;
847	return (ret);
848}
849
850/*
851 * Parse the items in a '-z guidance' value, and set the ofl_guideflags.
852 * A guidance option looks like this:
853 *
854 *	-z guidance[=item1,item2,...]
855 *
856 * Where each item specifies categories of guidance messages to suppress,
857 * each starting with the prefix 'no'. We allow arbitrary whitespace between
858 * the items, allow multiple ',' delimiters without an intervening item, and
859 * quietly ignore any items we don't recognize.
860 *
861 * -	Such items are likely to be known to newer versions of the linker,
862 *	and we do not want an older version of the linker to
863 *	complain about them.
864 *
865 * -	Times and standards can change, and so we wish to reserve the
866 *	right to make an old item that no longer makes sense go away.
867 *	Quietly ignoring unrecognized items facilitates this.
868 *
869 * However, we always display unrecognized items in debug output.
870 *
871 * entry:
872 *	ofl - Output descriptor
873 *	optarg - option string to be processed. This will either be a NULL
874 *		terminated 'guidance', or it will be 'guidance=' followed
875 *		by the item tokens as described above.
876 *
877 * exit:
878 *	Returns TRUE (1) on success, FALSE (0) on failure.
879 *
880 */
881static Boolean
882guidance_parse(Ofl_desc *ofl, char *optarg)
883{
884	typedef struct {
885		const char	*name;
886		ofl_guideflag_t	flag;
887	} item_desc;
888
889	static  item_desc items[] = {
890		{ MSG_ORIG(MSG_ARG_GUIDE_NO_ALL),	FLG_OFG_NO_ALL },
891
892		{ MSG_ORIG(MSG_ARG_GUIDE_NO_DEFS),	FLG_OFG_NO_DEFS },
893		{ MSG_ORIG(MSG_ARG_GUIDE_NO_DIRECT),	FLG_OFG_NO_DB },
894		{ MSG_ORIG(MSG_ARG_GUIDE_NO_LAZYLOAD),	FLG_OFG_NO_LAZY },
895		{ MSG_ORIG(MSG_ARG_GUIDE_NO_MAPFILE),	FLG_OFG_NO_MF },
896		{ MSG_ORIG(MSG_ARG_GUIDE_NO_TEXT),	FLG_OFG_NO_TEXT },
897		{ MSG_ORIG(MSG_ARG_GUIDE_NO_UNUSED),	FLG_OFG_NO_UNUSED },
898		{ NULL,					0 }
899	};
900
901	char		*lasts, *name;
902	item_desc	*item;
903	ofl_guideflag_t	ofl_guideflags = FLG_OFG_ENABLE;
904
905	/*
906	 * Skip the 'guidance' prefix. If NULL terminated, there are no
907	 * item values to parse. Otherwise, skip the '=' and parse the items.
908	 */
909	optarg += MSG_ARG_GUIDE_SIZE;
910	if (*optarg == '=') {
911		optarg++;
912
913		if ((name = libld_malloc(strlen(optarg) + 1)) == NULL)
914			return (FALSE);
915		(void) strcpy(name, optarg);
916
917		if ((name = strtok_r(name, MSG_ORIG(MSG_ARG_GUIDE_DELIM),
918		    &lasts)) != NULL) {
919			do {
920				for (item = items; item->name != NULL; item++)
921					if (strcasecmp(name, item->name) == 0)
922						break;
923				if (item->name == NULL) {
924					DBG_CALL(Dbg_args_guidance_unknown(
925					    ofl->ofl_lml, name));
926					continue;
927				}
928				ofl_guideflags |= item->flag;
929			} while ((name = strtok_r(NULL,
930			    MSG_ORIG(MSG_ARG_GUIDE_DELIM), &lasts)) != NULL);
931		}
932	}
933
934	/*
935	 * If -zguidance is used more than once, we take the first one. We
936	 * do this quietly if they have identical options, and with a warning
937	 * otherwise.
938	 */
939	if ((initial_guidance_flags & FLG_OFG_ENABLE) &&
940	    (ofl_guideflags != initial_guidance_flags)) {
941		ld_eprintf(ofl, ERR_WARNING_NF, MSG_INTL(MSG_ARG_MTONCE),
942		    MSG_ORIG(MSG_ARG_ZGUIDE));
943		return (TRUE);
944	}
945
946	/*
947	 * First time: Save the flags for comparison to any subsequent
948	 * -z guidance that comes along, and OR the resulting flags into
949	 * the flags kept in the output descriptor.
950	 */
951	initial_guidance_flags = ofl_guideflags;
952	ofl->ofl_guideflags |= ofl_guideflags;
953	return (TRUE);
954}
955
956/*
957 * Parse the -z assert-deflib option. This option can appear in two different
958 * forms:
959 *	-z assert-deflib
960 *	-z assert-deflib=libfred.so
961 *
962 * Either form enables this option, the latter form marks libfred.so as an
963 * exempt library from the check. It is valid to have multiple invocations of
964 * the second form. We silently ignore mulitple occurrences of the first form
965 * and multiple invocations of the first form when the second form also occurs.
966 *
967 * We only return false when we have an internal error, such as the failure of
968 * aplist_append. Every other time we return true, but we have the appropriate
969 * fatal flags set beacuse of the ld_eprintf.
970 */
971static int
972assdeflib_parse(Ofl_desc *ofl, char *optarg)
973{
974	size_t olen, mlen;
975	ofl->ofl_flags |= FLG_OF_ADEFLIB;
976
977	olen = strlen(optarg);
978	/* Minimum size of assert-deflib=lib%s.so */
979	mlen = MSG_ARG_ASSDEFLIB_SIZE + 1 + MSG_STR_LIB_SIZE +
980	    MSG_STR_SOEXT_SIZE;
981	if (olen > MSG_ARG_ASSDEFLIB_SIZE) {
982		if (optarg[MSG_ARG_ASSDEFLIB_SIZE] != '=') {
983			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ILLEGAL),
984			    MSG_ORIG(MSG_ARG_ASSDEFLIB), optarg);
985			return (TRUE);
986		}
987
988		if (strncmp(optarg + MSG_ARG_ASSDEFLIB_SIZE + 1,
989		    MSG_ORIG(MSG_STR_LIB), MSG_STR_LIB_SIZE) != 0 ||
990		    strcmp(optarg + olen - MSG_STR_SOEXT_SIZE,
991		    MSG_ORIG(MSG_STR_SOEXT)) != 0 || olen <= mlen) {
992			ld_eprintf(ofl, ERR_FATAL,
993			    MSG_INTL(MSG_ARG_ASSDEFLIB_MALFORMED), optarg);
994			return (TRUE);
995		}
996
997		if (aplist_append(&ofl->ofl_assdeflib, optarg +
998		    MSG_ARG_ASSDEFLIB_SIZE + 1, AL_CNT_ASSDEFLIB) == NULL)
999			return (FALSE);
1000	}
1001
1002	return (TRUE);
1003}
1004
1005static int	optitle = 0;
1006/*
1007 * Parsing options pass1 for process_flags().
1008 */
1009static uintptr_t
1010parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
1011{
1012	int	c, ndx = optind;
1013
1014	/*
1015	 * The -32, -64 and -ztarget options are special, in that we validate
1016	 * them, but otherwise ignore them. libld.so (this code) is called
1017	 * from the ld front end program. ld has already examined the
1018	 * arguments to determine the output class and machine type of the
1019	 * output object, as reflected in the version (32/64) of ld_main()
1020	 * that was called and the value of the 'mach' argument passed.
1021	 * By time execution reaches this point, these options have already
1022	 * been seen and acted on.
1023	 */
1024	while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1025
1026		switch (c) {
1027		case '3':
1028			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1029
1030			/*
1031			 * -32 is processed by ld to determine the output class.
1032			 * Here we sanity check the option incase some other
1033			 * -3* option is mistakenly passed to us.
1034			 */
1035			if (optarg[0] != '2')
1036				ld_eprintf(ofl, ERR_FATAL,
1037				    MSG_INTL(MSG_ARG_ILLEGAL),
1038				    MSG_ORIG(MSG_ARG_3), optarg);
1039			continue;
1040
1041		case '6':
1042			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1043
1044			/*
1045			 * -64 is processed by ld to determine the output class.
1046			 * Here we sanity check the option incase some other
1047			 * -6* option is mistakenly passed to us.
1048			 */
1049			if (optarg[0] != '4')
1050				ld_eprintf(ofl, ERR_FATAL,
1051				    MSG_INTL(MSG_ARG_ILLEGAL),
1052				    MSG_ORIG(MSG_ARG_6), optarg);
1053			continue;
1054
1055		case 'a':
1056			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1057			aflag = TRUE;
1058			break;
1059
1060		case 'b':
1061			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1062			bflag = TRUE;
1063
1064			/*
1065			 * This is a hack, and may be undone later.
1066			 * The -b option is only used to build the Unix
1067			 * kernel and its related kernel-mode modules.
1068			 * We do not want those files to get a .SUNW_ldynsym
1069			 * section. At least for now, the kernel makes no
1070			 * use of .SUNW_ldynsym, and we do not want to use
1071			 * the space to hold it. Therefore, we overload
1072			 * the use of -b to also imply -znoldynsym.
1073			 */
1074			ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1075			break;
1076
1077		case 'c':
1078			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1079			if (ofl->ofl_config)
1080				ld_eprintf(ofl, ERR_WARNING_NF,
1081				    MSG_INTL(MSG_ARG_MTONCE),
1082				    MSG_ORIG(MSG_ARG_C));
1083			else
1084				ofl->ofl_config = optarg;
1085			break;
1086
1087		case 'C':
1088			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1089			demangle_flag = 1;
1090			break;
1091
1092		case 'd':
1093			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1094			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1095				if (dflag != SET_UNKNOWN)
1096					ld_eprintf(ofl, ERR_WARNING_NF,
1097					    MSG_INTL(MSG_ARG_MTONCE),
1098					    MSG_ORIG(MSG_ARG_D));
1099				else
1100					dflag = SET_FALSE;
1101			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1102				if (dflag != SET_UNKNOWN)
1103					ld_eprintf(ofl, ERR_WARNING_NF,
1104					    MSG_INTL(MSG_ARG_MTONCE),
1105					    MSG_ORIG(MSG_ARG_D));
1106				else
1107					dflag = SET_TRUE;
1108			} else {
1109				ld_eprintf(ofl, ERR_FATAL,
1110				    MSG_INTL(MSG_ARG_ILLEGAL),
1111				    MSG_ORIG(MSG_ARG_D), optarg);
1112			}
1113			break;
1114
1115		case 'e':
1116			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1117			if (ofl->ofl_entry)
1118				ld_eprintf(ofl, ERR_WARNING_NF,
1119				    MSG_INTL(MSG_MARG_MTONCE),
1120				    MSG_INTL(MSG_MARG_ENTRY));
1121			else
1122				ofl->ofl_entry = (void *)optarg;
1123			break;
1124
1125		case 'f':
1126			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1127			if (ofl->ofl_filtees &&
1128			    (!(ofl->ofl_flags & FLG_OF_AUX))) {
1129				ld_eprintf(ofl, ERR_FATAL,
1130				    MSG_INTL(MSG_MARG_INCOMP),
1131				    MSG_INTL(MSG_MARG_FILTER_AUX),
1132				    MSG_INTL(MSG_MARG_FILTER));
1133			} else {
1134				if ((ofl->ofl_filtees =
1135				    add_string(ofl->ofl_filtees, optarg)) ==
1136				    (const char *)S_ERROR)
1137					return (S_ERROR);
1138				ofl->ofl_flags |= FLG_OF_AUX;
1139			}
1140			break;
1141
1142		case 'F':
1143			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1144			if (ofl->ofl_filtees &&
1145			    (ofl->ofl_flags & FLG_OF_AUX)) {
1146				ld_eprintf(ofl, ERR_FATAL,
1147				    MSG_INTL(MSG_MARG_INCOMP),
1148				    MSG_INTL(MSG_MARG_FILTER),
1149				    MSG_INTL(MSG_MARG_FILTER_AUX));
1150			} else {
1151				if ((ofl->ofl_filtees =
1152				    add_string(ofl->ofl_filtees, optarg)) ==
1153				    (const char *)S_ERROR)
1154					return (S_ERROR);
1155			}
1156			break;
1157
1158		case 'h':
1159			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1160			if (ofl->ofl_soname)
1161				ld_eprintf(ofl, ERR_WARNING_NF,
1162				    MSG_INTL(MSG_MARG_MTONCE),
1163				    MSG_INTL(MSG_MARG_SONAME));
1164			else
1165				ofl->ofl_soname = (const char *)optarg;
1166			break;
1167
1168		case 'i':
1169			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1170			ofl->ofl_flags |= FLG_OF_IGNENV;
1171			break;
1172
1173		case 'I':
1174			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1175			if (ofl->ofl_interp)
1176				ld_eprintf(ofl, ERR_WARNING_NF,
1177				    MSG_INTL(MSG_ARG_MTONCE),
1178				    MSG_ORIG(MSG_ARG_CI));
1179			else
1180				ofl->ofl_interp = (const char *)optarg;
1181			break;
1182
1183		case 'l':
1184			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1185			/*
1186			 * For now, count any library as a shared object.  This
1187			 * is used to size the internal symbol cache.  This
1188			 * value is recalculated later on actual file processing
1189			 * to get an accurate shared object count.
1190			 */
1191			ofl->ofl_soscnt++;
1192			break;
1193
1194		case 'm':
1195			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1196			ofl->ofl_flags |= FLG_OF_GENMAP;
1197			break;
1198
1199		case 'o':
1200			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1201			if (ofl->ofl_name)
1202				ld_eprintf(ofl, ERR_WARNING_NF,
1203				    MSG_INTL(MSG_MARG_MTONCE),
1204				    MSG_INTL(MSG_MARG_OUTFILE));
1205			else
1206				ofl->ofl_name = (const char *)optarg;
1207			break;
1208
1209		case 'p':
1210			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1211
1212			/*
1213			 * Multiple instances of this option may occur.  Each
1214			 * additional instance is effectively concatenated to
1215			 * the previous separated by a colon.
1216			 */
1217			if (*optarg != '\0') {
1218				if ((ofl->ofl_audit =
1219				    add_string(ofl->ofl_audit,
1220				    optarg)) == (const char *)S_ERROR)
1221					return (S_ERROR);
1222			}
1223			break;
1224
1225		case 'P':
1226			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1227
1228			/*
1229			 * Multiple instances of this option may occur.  Each
1230			 * additional instance is effectively concatenated to
1231			 * the previous separated by a colon.
1232			 */
1233			if (*optarg != '\0') {
1234				if ((ofl->ofl_depaudit =
1235				    add_string(ofl->ofl_depaudit,
1236				    optarg)) == (const char *)S_ERROR)
1237					return (S_ERROR);
1238			}
1239			break;
1240
1241		case 'r':
1242			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1243			otype = OT_RELOC;
1244			break;
1245
1246		case 'R':
1247			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1248
1249			/*
1250			 * Multiple instances of this option may occur.  Each
1251			 * additional instance is effectively concatenated to
1252			 * the previous separated by a colon.
1253			 */
1254			if (*optarg != '\0') {
1255				if ((ofl->ofl_rpath =
1256				    add_string(ofl->ofl_rpath,
1257				    optarg)) == (const char *)S_ERROR)
1258					return (S_ERROR);
1259			}
1260			break;
1261
1262		case 's':
1263			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1264			sflag = TRUE;
1265			break;
1266
1267		case 't':
1268			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1269			ofl->ofl_flags |= FLG_OF_NOWARN;
1270			break;
1271
1272		case 'u':
1273			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1274			break;
1275
1276		case 'z':
1277			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1278
1279			/*
1280			 * Skip comma that might be present between -z and its
1281			 * argument (e.g. if -Wl,-z,assert-deflib was passed).
1282			 */
1283			if (strncmp(optarg, MSG_ORIG(MSG_STR_COMMA),
1284			    MSG_STR_COMMA_SIZE) == 0)
1285				optarg++;
1286
1287			/*
1288			 * For specific help, print our usage message and exit
1289			 * immediately to ensure a 0 return code.
1290			 */
1291			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
1292			    MSG_ARG_HELP_SIZE) == 0) {
1293				usage_mesg(TRUE);
1294				exit(0);
1295			}
1296
1297			/*
1298			 * For some options set a flag - further consistancy
1299			 * checks will be carried out in check_flags().
1300			 */
1301			if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1302			    MSG_ARG_LD32_SIZE) == 0) ||
1303			    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1304			    MSG_ARG_LD64_SIZE) == 0)) {
1305				if (createargv(ofl, usage) == S_ERROR)
1306					return (S_ERROR);
1307
1308			} else if (
1309			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
1310				if (zdflag != SET_UNKNOWN)
1311					ld_eprintf(ofl, ERR_WARNING_NF,
1312					    MSG_INTL(MSG_ARG_MTONCE),
1313					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
1314				else
1315					zdflag = SET_TRUE;
1316				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1317			} else if (strcmp(optarg,
1318			    MSG_ORIG(MSG_ARG_NODEFS)) == 0) {
1319				if (zdflag != SET_UNKNOWN)
1320					ld_eprintf(ofl, ERR_WARNING_NF,
1321					    MSG_INTL(MSG_ARG_MTONCE),
1322					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
1323				else
1324					zdflag = SET_FALSE;
1325				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1326			} else if (strcmp(optarg,
1327			    MSG_ORIG(MSG_ARG_TEXT)) == 0) {
1328				if (ztflag &&
1329				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT)))
1330					ld_eprintf(ofl, ERR_FATAL,
1331					    MSG_INTL(MSG_ARG_INCOMP),
1332					    MSG_ORIG(MSG_ARG_ZTEXT),
1333					    ztflag);
1334				ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
1335			} else if (strcmp(optarg,
1336			    MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
1337				if (ztflag &&
1338				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF)))
1339					ld_eprintf(ofl, ERR_FATAL,
1340					    MSG_INTL(MSG_ARG_INCOMP),
1341					    MSG_ORIG(MSG_ARG_ZTEXTOFF),
1342					    ztflag);
1343				ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
1344			} else if (strcmp(optarg,
1345			    MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
1346				if (ztflag &&
1347				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN)))
1348					ld_eprintf(ofl, ERR_FATAL,
1349					    MSG_INTL(MSG_ARG_INCOMP),
1350					    MSG_ORIG(MSG_ARG_ZTEXTWARN),
1351					    ztflag);
1352				ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
1353
1354			/*
1355			 * For other options simply set the ofl flags directly.
1356			 */
1357			} else if (strcmp(optarg,
1358			    MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
1359				ofl->ofl_flags1 |= FLG_OF1_RESCAN;
1360			} else if (strcmp(optarg,
1361			    MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
1362				ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
1363			} else if (strcmp(optarg,
1364			    MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
1365				zlflag = TRUE;
1366			} else if (strcmp(optarg,
1367			    MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
1368				ofl->ofl_dtflags_1 |= DF_1_NORELOC;
1369			} else if (strcmp(optarg,
1370			    MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
1371				ofl->ofl_flags |= FLG_OF_NOVERSEC;
1372			} else if (strcmp(optarg,
1373			    MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
1374				ofl->ofl_flags |= FLG_OF_MULDEFS;
1375			} else if (strcmp(optarg,
1376			    MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
1377				ofl->ofl_flags |= FLG_OF_REDLSYM;
1378			} else if (strcmp(optarg,
1379			    MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
1380				ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
1381			} else if (strcmp(optarg,
1382			    MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
1383				ofl->ofl_dtflags_1 |= DF_1_NODELETE;
1384			} else if (strcmp(optarg,
1385			    MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
1386				ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
1387			} else if (strcmp(optarg,
1388			    MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
1389				ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
1390			} else if (strcmp(optarg,
1391			    MSG_ORIG(MSG_ARG_NOW)) == 0) {
1392				ofl->ofl_dtflags_1 |= DF_1_NOW;
1393				ofl->ofl_dtflags |= DF_BIND_NOW;
1394			} else if (strcmp(optarg,
1395			    MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
1396				ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
1397				ofl->ofl_dtflags |= DF_ORIGIN;
1398			} else if (strcmp(optarg,
1399			    MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1400				ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1401			} else if (strcmp(optarg,
1402			    MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1403				ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1404			} else if (strcmp(optarg,
1405			    MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1406				ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1407			} else if (strcmp(optarg,
1408			    MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1409				ofl->ofl_flags |= FLG_OF_VERBOSE;
1410			} else if (strcmp(optarg,
1411			    MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1412				ofl->ofl_flags |= FLG_OF_COMREL;
1413			} else if (strcmp(optarg,
1414			    MSG_ORIG(MSG_ARG_NOCOMBRELOC)) == 0) {
1415				ofl->ofl_flags |= FLG_OF_NOCOMREL;
1416			} else if (strcmp(optarg,
1417			    MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1418				ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1419			} else if (strcmp(optarg,
1420			    MSG_ORIG(MSG_ARG_NOINTERP)) == 0) {
1421				ofl->ofl_flags1 |= FLG_OF1_NOINTRP;
1422			} else if (strcmp(optarg,
1423			    MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1424				zinflag = TRUE;
1425			} else if (strcmp(optarg,
1426			    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1427				ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1428			} else if (strcmp(optarg,
1429			    MSG_ORIG(MSG_ARG_RELAXRELOC)) == 0) {
1430				ofl->ofl_flags1 |= FLG_OF1_RLXREL;
1431			} else if (strcmp(optarg,
1432			    MSG_ORIG(MSG_ARG_NORELAXRELOC)) == 0) {
1433				ofl->ofl_flags1 |= FLG_OF1_NRLXREL;
1434			} else if (strcmp(optarg,
1435			    MSG_ORIG(MSG_ARG_NOLDYNSYM)) == 0) {
1436				ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1437			} else if (strcmp(optarg,
1438			    MSG_ORIG(MSG_ARG_GLOBAUDIT)) == 0) {
1439				ofl->ofl_dtflags_1 |= DF_1_GLOBAUDIT;
1440			} else if (strcmp(optarg,
1441			    MSG_ORIG(MSG_ARG_NOSIGHANDLER)) == 0) {
1442				ofl->ofl_flags1 |= FLG_OF1_NOSGHND;
1443			} else if (strcmp(optarg,
1444			    MSG_ORIG(MSG_ARG_SYMBOLCAP)) == 0) {
1445				ofl->ofl_flags |= FLG_OF_OTOSCAP;
1446
1447			/*
1448			 * Check archive group usage
1449			 *	-z rescan-start ... -z rescan-end
1450			 * to ensure they don't overlap and are well formed.
1451			 */
1452			} else if (strcmp(optarg,
1453			    MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1454				if (ofl->ofl_ars_gsandx == 0) {
1455					ofl->ofl_ars_gsandx = ndx;
1456				} else if (ofl->ofl_ars_gsandx > 0) {
1457					/* Another group is still open */
1458					ld_eprintf(ofl, ERR_FATAL,
1459					    MSG_INTL(MSG_ARG_AR_GRP_OLAP),
1460					    MSG_INTL(MSG_MARG_AR_GRPS));
1461					/* Don't report cascading errors */
1462					ofl->ofl_ars_gsandx = -1;
1463				}
1464			} else if (strcmp(optarg,
1465			    MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1466				if (ofl->ofl_ars_gsandx > 0) {
1467					ofl->ofl_ars_gsandx = 0;
1468				} else if (ofl->ofl_ars_gsandx == 0) {
1469					/* There was no matching begin */
1470					ld_eprintf(ofl, ERR_FATAL,
1471					    MSG_INTL(MSG_ARG_AR_GRP_BAD),
1472					    MSG_INTL(MSG_MARG_AR_GRP_END),
1473					    MSG_INTL(MSG_MARG_AR_GRP_START));
1474					/* Don't report cascading errors */
1475					ofl->ofl_ars_gsandx = -1;
1476				}
1477
1478			/*
1479			 * If -z wrap is seen, enter the symbol to be wrapped
1480			 * into the wrap AVL tree.
1481			 */
1482			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_WRAP),
1483			    MSG_ARG_WRAP_SIZE) == 0) {
1484				if (ld_wrap_enter(ofl,
1485				    optarg + MSG_ARG_WRAP_SIZE) == NULL)
1486					return (S_ERROR);
1487			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASLR),
1488			    MSG_ARG_ASLR_SIZE) == 0) {
1489				char *p = optarg + MSG_ARG_ASLR_SIZE;
1490				if (*p == '\0') {
1491					ofl->ofl_aslr = 1;
1492				} else if (*p == '=') {
1493					p++;
1494
1495					if ((strcmp(p,
1496					    MSG_ORIG(MSG_ARG_ENABLED)) == 0) ||
1497					    (strcmp(p,
1498					    MSG_ORIG(MSG_ARG_ENABLE)) == 0)) {
1499						ofl->ofl_aslr = 1;
1500					} else if ((strcmp(p,
1501					    MSG_ORIG(MSG_ARG_DISABLED)) == 0) ||
1502					    (strcmp(p,
1503					    MSG_ORIG(MSG_ARG_DISABLE)) == 0)) {
1504						ofl->ofl_aslr = -1;
1505					} else {
1506						ld_eprintf(ofl, ERR_FATAL,
1507						    MSG_INTL(MSG_ARG_ILLEGAL),
1508						    MSG_ORIG(MSG_ARG_ZASLR), p);
1509						return (S_ERROR);
1510					}
1511				} else {
1512					ld_eprintf(ofl, ERR_FATAL,
1513					    MSG_INTL(MSG_ARG_ILLEGAL),
1514					    MSG_ORIG(MSG_ARG_Z), optarg);
1515					return (S_ERROR);
1516				}
1517			} else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
1518			    MSG_ARG_GUIDE_SIZE) == 0) &&
1519			    ((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
1520			    (optarg[MSG_ARG_GUIDE_SIZE] == '\0'))) {
1521				if (!guidance_parse(ofl, optarg))
1522					return (S_ERROR);
1523			} else if (strcmp(optarg,
1524			    MSG_ORIG(MSG_ARG_FATWARN)) == 0) {
1525				if (zfwflag  == SET_FALSE) {
1526					ld_eprintf(ofl, ERR_WARNING_NF,
1527					    MSG_INTL(MSG_ARG_MTONCE),
1528					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1529				} else {
1530					zfwflag = SET_TRUE;
1531					ofl->ofl_flags |= FLG_OF_FATWARN;
1532				}
1533			} else if (strcmp(optarg,
1534			    MSG_ORIG(MSG_ARG_NOFATWARN)) == 0) {
1535				if (zfwflag  == SET_TRUE)
1536					ld_eprintf(ofl, ERR_WARNING_NF,
1537					    MSG_INTL(MSG_ARG_MTONCE),
1538					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1539				else
1540					zfwflag = SET_FALSE;
1541
1542			/*
1543			 * Process everything related to -z assert-deflib. This
1544			 * must be done in pass 1 because it gets used in pass
1545			 * 2.
1546			 */
1547			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASSDEFLIB),
1548			    MSG_ARG_ASSDEFLIB_SIZE) == 0) {
1549				if (assdeflib_parse(ofl, optarg) != TRUE)
1550					return (S_ERROR);
1551
1552			/*
1553			 * Process new-style output type specification, which
1554			 * we'll use in pass 2 and throughout.
1555			 */
1556			} else if (strncmp(optarg, MSG_ORIG(MSG_ARG_TYPE),
1557			    MSG_ARG_TYPE_SIZE) == 0) {
1558				char *p = optarg + MSG_ARG_TYPE_SIZE;
1559				if (*p != '=') {
1560					ld_eprintf(ofl, ERR_FATAL,
1561					    MSG_INTL(MSG_ARG_ILLEGAL),
1562					    MSG_ORIG(MSG_ARG_Z), optarg);
1563					return (S_ERROR);
1564				}
1565
1566				p++;
1567				if (strcmp(p,
1568				    MSG_ORIG(MSG_ARG_TYPE_RELOC)) == 0) {
1569					otype = OT_RELOC;
1570				} else if (strcmp(p,
1571				    MSG_ORIG(MSG_ARG_TYPE_EXEC)) == 0) {
1572					otype = OT_EXEC;
1573				} else if (strcmp(p,
1574				    MSG_ORIG(MSG_ARG_TYPE_SHARED)) == 0) {
1575					otype = OT_SHARED;
1576				} else if (strcmp(p,
1577				    MSG_ORIG(MSG_ARG_TYPE_KMOD)) == 0) {
1578					otype = OT_KMOD;
1579				} else {
1580					ld_eprintf(ofl, ERR_FATAL,
1581					    MSG_INTL(MSG_ARG_ILLEGAL),
1582					    MSG_ORIG(MSG_ARG_Z), optarg);
1583					return (S_ERROR);
1584				}
1585			/*
1586			 * The following options just need validation as they
1587			 * are interpreted on the second pass through the
1588			 * command line arguments.
1589			 */
1590			} else if (
1591			    strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1592			    MSG_ARG_INITARRAY_SIZE) &&
1593			    strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1594			    MSG_ARG_FINIARRAY_SIZE) &&
1595			    strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1596			    MSG_ARG_PREINITARRAY_SIZE) &&
1597			    strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1598			    MSG_ARG_RTLDINFO_SIZE) &&
1599			    strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1600			    MSG_ARG_DTRACE_SIZE) &&
1601			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1602			    strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1603			    strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1604			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1605			    strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1606			    strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1607			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1608			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1609			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
1610			    strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1611			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
1612			    strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
1613			    strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
1614			    MSG_ARG_TARGET_SIZE) &&
1615			    strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
1616			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
1617				ld_eprintf(ofl, ERR_FATAL,
1618				    MSG_INTL(MSG_ARG_ILLEGAL),
1619				    MSG_ORIG(MSG_ARG_Z), optarg);
1620			}
1621
1622			break;
1623
1624		case 'D':
1625			/*
1626			 * If we have not yet read any input files go ahead
1627			 * and process any debugging options (this allows any
1628			 * argument processing, entrance criteria and library
1629			 * initialization to be displayed).  Otherwise, if an
1630			 * input file has been seen, skip interpretation until
1631			 * process_files (this allows debugging to be turned
1632			 * on and off around individual groups of files).
1633			 */
1634			Dflag = 1;
1635			if (ofl->ofl_objscnt == 0) {
1636				if (dbg_setup(ofl, optarg, 2) == 0)
1637					return (S_ERROR);
1638			}
1639
1640			/*
1641			 * A diagnostic can only be provided after dbg_setup().
1642			 * As this is the first diagnostic that can be produced
1643			 * by ld(1), issue a title for timing and basic output.
1644			 */
1645			if ((optitle == 0) && DBG_ENABLED) {
1646				optitle++;
1647				DBG_CALL(Dbg_basic_options(ofl->ofl_lml));
1648			}
1649			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1650			break;
1651
1652		case 'B':
1653			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1654			if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1655				if (Bdflag == SET_FALSE) {
1656					ld_eprintf(ofl, ERR_FATAL,
1657					    MSG_INTL(MSG_ARG_INCOMP),
1658					    MSG_ORIG(MSG_ARG_BNODIRECT),
1659					    MSG_ORIG(MSG_ARG_BDIRECT));
1660				} else {
1661					Bdflag = SET_TRUE;
1662					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1663				}
1664			} else if (strcmp(optarg,
1665			    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1666				if (Bdflag == SET_TRUE) {
1667					ld_eprintf(ofl, ERR_FATAL,
1668					    MSG_INTL(MSG_ARG_INCOMP),
1669					    MSG_ORIG(MSG_ARG_BDIRECT),
1670					    MSG_ORIG(MSG_ARG_BNODIRECT));
1671				} else {
1672					Bdflag = SET_FALSE;
1673					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1674				}
1675			} else if (strcmp(optarg,
1676			    MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1677				Bsflag = TRUE;
1678			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1679				ofl->ofl_flags |= FLG_OF_PROCRED;
1680			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1681				Blflag = TRUE;
1682			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1683				Bgflag = TRUE;
1684			else if (strcmp(optarg,
1685			    MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1686				Beflag = TRUE;
1687			else if (strcmp(optarg,
1688			    MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
1689				ld_eprintf(ofl, ERR_WARNING,
1690				    MSG_INTL(MSG_ARG_UNSUPPORTED),
1691				    MSG_ORIG(MSG_ARG_BTRANSLATOR));
1692			} else if (strcmp(optarg,
1693			    MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1694			    strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1695				ld_eprintf(ofl, ERR_FATAL,
1696				    MSG_INTL(MSG_ARG_ILLEGAL),
1697				    MSG_ORIG(MSG_ARG_CB), optarg);
1698			}
1699			break;
1700
1701		case 'G':
1702			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1703			otype = OT_SHARED;
1704			break;
1705
1706		case 'L':
1707			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1708			break;
1709
1710		case 'M':
1711			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1712			if (aplist_append(&(ofl->ofl_maps), optarg,
1713			    AL_CNT_OFL_MAPFILES) == NULL)
1714				return (S_ERROR);
1715			break;
1716
1717		case 'N':
1718			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1719			break;
1720
1721		case 'Q':
1722			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1723			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1724				if (Qflag != SET_UNKNOWN)
1725					ld_eprintf(ofl, ERR_WARNING_NF,
1726					    MSG_INTL(MSG_ARG_MTONCE),
1727					    MSG_ORIG(MSG_ARG_CQ));
1728				else
1729					Qflag = SET_FALSE;
1730			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1731				if (Qflag != SET_UNKNOWN)
1732					ld_eprintf(ofl, ERR_WARNING_NF,
1733					    MSG_INTL(MSG_ARG_MTONCE),
1734					    MSG_ORIG(MSG_ARG_CQ));
1735				else
1736					Qflag = SET_TRUE;
1737			} else {
1738				ld_eprintf(ofl, ERR_FATAL,
1739				    MSG_INTL(MSG_ARG_ILLEGAL),
1740				    MSG_ORIG(MSG_ARG_CQ), optarg);
1741			}
1742			break;
1743
1744		case 'S':
1745			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1746			if (aplist_append(&lib_support, optarg,
1747			    AL_CNT_SUPPORT) == NULL)
1748				return (S_ERROR);
1749			break;
1750
1751		case 'V':
1752			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1753			if (!Vflag)
1754				(void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1755				    ofl->ofl_sgsid);
1756			Vflag = TRUE;
1757			break;
1758
1759		case 'Y':
1760			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1761			if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1762				if (Llibdir)
1763					ld_eprintf(ofl, ERR_WARNING_NF,
1764					    MSG_INTL(MSG_ARG_MTONCE),
1765					    MSG_ORIG(MSG_ARG_CYL));
1766				else
1767					Llibdir = optarg + 2;
1768			} else if (strncmp(optarg,
1769			    MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1770				if (Ulibdir)
1771					ld_eprintf(ofl, ERR_WARNING_NF,
1772					    MSG_INTL(MSG_ARG_MTONCE),
1773					    MSG_ORIG(MSG_ARG_CYU));
1774				else
1775					Ulibdir = optarg + 2;
1776			} else if (strncmp(optarg,
1777			    MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1778				if (Plibpath)
1779					ld_eprintf(ofl, ERR_WARNING_NF,
1780					    MSG_INTL(MSG_ARG_MTONCE),
1781					    MSG_ORIG(MSG_ARG_CYP));
1782				else
1783					Plibpath = optarg + 2;
1784			} else {
1785				ld_eprintf(ofl, ERR_FATAL,
1786				    MSG_INTL(MSG_ARG_ILLEGAL),
1787				    MSG_ORIG(MSG_ARG_CY), optarg);
1788			}
1789			break;
1790
1791		case '?':
1792			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1793			/*
1794			 * If the option character is '-', we're looking at a
1795			 * long option which couldn't be translated, display a
1796			 * more useful error.
1797			 */
1798			if (optopt == '-') {
1799				eprintf(ofl->ofl_lml, ERR_FATAL,
1800				    MSG_INTL(MSG_ARG_LONG_UNKNOWN),
1801				    argv[optind-1]);
1802			} else {
1803				eprintf(ofl->ofl_lml, ERR_FATAL,
1804				    MSG_INTL(MSG_ARG_UNKNOWN), optopt);
1805			}
1806			(*usage)++;
1807			break;
1808
1809		default:
1810			break;
1811		}
1812
1813		/*
1814		 * Update the argument index for the next getopt() iteration.
1815		 */
1816		ndx = optind;
1817	}
1818	return (1);
1819}
1820
1821/*
1822 * Parsing options pass2 for
1823 */
1824static uintptr_t
1825parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1826{
1827	int	c, ndx = optind;
1828
1829	while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1830		Ifl_desc	*ifl;
1831		Sym_desc	*sdp;
1832
1833		switch (c) {
1834			case 'l':
1835				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1836				    optarg));
1837				if (ld_find_library(optarg, ofl) == S_ERROR)
1838					return (S_ERROR);
1839				break;
1840			case 'B':
1841				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1842				    optarg));
1843				if (strcmp(optarg,
1844				    MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1845					if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1846						ofl->ofl_flags |=
1847						    FLG_OF_DYNLIBS;
1848					else {
1849						ld_eprintf(ofl, ERR_FATAL,
1850						    MSG_INTL(MSG_ARG_ST_INCOMP),
1851						    MSG_ORIG(MSG_ARG_BDYNAMIC));
1852					}
1853				} else if (strcmp(optarg,
1854				    MSG_ORIG(MSG_ARG_STATIC)) == 0)
1855					ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1856				break;
1857			case 'L':
1858				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1859				    optarg));
1860				if (ld_add_libdir(ofl, optarg) == S_ERROR)
1861					return (S_ERROR);
1862				break;
1863			case 'N':
1864				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1865				    optarg));
1866				/*
1867				 * Record DT_NEEDED string
1868				 */
1869				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
1870					ld_eprintf(ofl, ERR_FATAL,
1871					    MSG_INTL(MSG_ARG_ST_INCOMP),
1872					    MSG_ORIG(MSG_ARG_CN));
1873				if (((ifl = libld_calloc(1,
1874				    sizeof (Ifl_desc))) == NULL) ||
1875				    (aplist_append(&ofl->ofl_sos, ifl,
1876				    AL_CNT_OFL_LIBS) == NULL))
1877					return (S_ERROR);
1878
1879				ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1880				ifl->ifl_soname = optarg;
1881				ifl->ifl_flags = (FLG_IF_NEEDSTR |
1882				    FLG_IF_FILEREF | FLG_IF_DEPREQD);
1883
1884				break;
1885			case 'D':
1886				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1887				    optarg));
1888				(void) dbg_setup(ofl, optarg, 3);
1889				break;
1890			case 'u':
1891				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1892				    optarg));
1893				if (ld_sym_add_u(optarg, ofl,
1894				    MSG_STR_COMMAND) == (Sym_desc *)S_ERROR)
1895					return (S_ERROR);
1896				break;
1897			case 'z':
1898				DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1899				    optarg));
1900				if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1901				    MSG_ARG_LD32_SIZE) == 0) ||
1902				    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1903				    MSG_ARG_LD64_SIZE) == 0)) {
1904					if (createargv(ofl, 0) == S_ERROR)
1905						return (S_ERROR);
1906				} else if (strcmp(optarg,
1907				    MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1908					ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1909					ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1910				} else if (strcmp(optarg,
1911				    MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1912					ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1913					ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1914				} else if (strcmp(optarg,
1915				    MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1916					ofl->ofl_flags1 &=
1917					    ~(FLG_OF1_ALLEXRT |
1918					    FLG_OF1_WEAKEXT);
1919				} else if (strcmp(optarg,
1920				    MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1921					ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1922					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1923				} else if (strcmp(optarg,
1924				    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1925					ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1926					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1927				} else if (strcmp(optarg,
1928				    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1929					ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1930				} else if (strcmp(optarg,
1931				    MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1932					ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1933				} else if (strcmp(optarg,
1934				    MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1935					ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1936					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1937				} else if (strcmp(optarg,
1938				    MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1939					ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1940					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1941				} else if (strcmp(optarg,
1942				    MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1943					ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1944				} else if (strcmp(optarg,
1945				    MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1946					ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1947				} else if (strncmp(optarg,
1948				    MSG_ORIG(MSG_ARG_INITARRAY),
1949				    MSG_ARG_INITARRAY_SIZE) == 0) {
1950					if (((sdp = ld_sym_add_u(optarg +
1951					    MSG_ARG_INITARRAY_SIZE, ofl,
1952					    MSG_STR_COMMAND)) ==
1953					    (Sym_desc *)S_ERROR) ||
1954					    (aplist_append(&ofl->ofl_initarray,
1955					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1956						return (S_ERROR);
1957				} else if (strncmp(optarg,
1958				    MSG_ORIG(MSG_ARG_FINIARRAY),
1959				    MSG_ARG_FINIARRAY_SIZE) == 0) {
1960					if (((sdp = ld_sym_add_u(optarg +
1961					    MSG_ARG_FINIARRAY_SIZE, ofl,
1962					    MSG_STR_COMMAND)) ==
1963					    (Sym_desc *)S_ERROR) ||
1964					    (aplist_append(&ofl->ofl_finiarray,
1965					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1966						return (S_ERROR);
1967				} else if (strncmp(optarg,
1968				    MSG_ORIG(MSG_ARG_PREINITARRAY),
1969				    MSG_ARG_PREINITARRAY_SIZE) == 0) {
1970					if (((sdp = ld_sym_add_u(optarg +
1971					    MSG_ARG_PREINITARRAY_SIZE, ofl,
1972					    MSG_STR_COMMAND)) ==
1973					    (Sym_desc *)S_ERROR) ||
1974					    (aplist_append(&ofl->ofl_preiarray,
1975					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1976						return (S_ERROR);
1977				} else if (strncmp(optarg,
1978				    MSG_ORIG(MSG_ARG_RTLDINFO),
1979				    MSG_ARG_RTLDINFO_SIZE) == 0) {
1980					if (((sdp = ld_sym_add_u(optarg +
1981					    MSG_ARG_RTLDINFO_SIZE, ofl,
1982					    MSG_STR_COMMAND)) ==
1983					    (Sym_desc *)S_ERROR) ||
1984					    (aplist_append(&ofl->ofl_rtldinfo,
1985					    sdp, AL_CNT_OFL_ARRAYS) == NULL))
1986						return (S_ERROR);
1987				} else if (strncmp(optarg,
1988				    MSG_ORIG(MSG_ARG_DTRACE),
1989				    MSG_ARG_DTRACE_SIZE) == 0) {
1990					if ((sdp = ld_sym_add_u(optarg +
1991					    MSG_ARG_DTRACE_SIZE, ofl,
1992					    MSG_STR_COMMAND)) ==
1993					    (Sym_desc *)S_ERROR)
1994						return (S_ERROR);
1995					ofl->ofl_dtracesym = sdp;
1996				} else if (strcmp(optarg,
1997				    MSG_ORIG(MSG_ARG_RESCAN_NOW)) == 0) {
1998					if (ld_rescan_archives(ofl, 0, ndx) ==
1999					    S_ERROR)
2000						return (S_ERROR);
2001				} else if (strcmp(optarg,
2002				    MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
2003					ofl->ofl_ars_gsndx = ofl->ofl_arscnt;
2004					ofl->ofl_ars_gsandx = ndx;
2005				} else if (strcmp(optarg,
2006				    MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
2007					if (ld_rescan_archives(ofl, 1, ndx) ==
2008					    S_ERROR)
2009						return (S_ERROR);
2010				} else if (strcmp(optarg,
2011				    MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
2012					ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
2013				} else if (strcmp(optarg,
2014				    MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
2015					ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
2016				}
2017			default:
2018				break;
2019		}
2020
2021		/*
2022		 * Update the argument index for the next getopt() iteration.
2023		 */
2024		ndx = optind;
2025	}
2026	return (1);
2027}
2028
2029/*
2030 *
2031 * Pass 1 -- process_flags: collects all options and sets flags
2032 */
2033static uintptr_t
2034process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
2035{
2036	for (; optind < argc; optind++) {
2037		/*
2038		 * If we detect some more options return to getopt().
2039		 * Checking argv[optind][1] against null prevents a forever
2040		 * loop if an unadorned `-' argument is passed to us.
2041		 */
2042		while ((optind < argc) && (argv[optind][0] == '-')) {
2043			if (argv[optind][1] != '\0') {
2044				if (parseopt_pass1(ofl, argc, argv,
2045				    usage) == S_ERROR)
2046					return (S_ERROR);
2047			} else if (++optind < argc)
2048				continue;
2049		}
2050		if (optind >= argc)
2051			break;
2052		ofl->ofl_objscnt++;
2053	}
2054
2055	/* Did an unterminated archive group run off the end? */
2056	if (ofl->ofl_ars_gsandx > 0) {
2057		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
2058		    MSG_INTL(MSG_MARG_AR_GRP_START),
2059		    MSG_INTL(MSG_MARG_AR_GRP_END));
2060		return (S_ERROR);
2061	}
2062
2063	return (1);
2064}
2065
2066uintptr_t
2067ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
2068{
2069	int	usage = 0;	/* Collect all argument errors before exit */
2070
2071	if (argc < 2) {
2072		usage_mesg(FALSE);
2073		return (S_ERROR);
2074	}
2075
2076	/*
2077	 * Option handling
2078	 */
2079	opterr = 0;
2080	optind = 1;
2081	if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
2082		return (S_ERROR);
2083
2084	/*
2085	 * Having parsed everything, did we have any usage errors.
2086	 */
2087	if (usage) {
2088		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
2089		return (S_ERROR);
2090	}
2091
2092	return (check_flags(ofl, argc));
2093}
2094
2095/*
2096 * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
2097 * files.
2098 */
2099static uintptr_t
2100process_files_com(Ofl_desc *ofl, int argc, char **argv)
2101{
2102	for (; optind < argc; optind++) {
2103		int		fd;
2104		uintptr_t	open_ret;
2105		char		*path;
2106		Rej_desc	rej = { 0 };
2107
2108		/*
2109		 * If we detect some more options return to getopt().
2110		 * Checking argv[optind][1] against null prevents a forever
2111		 * loop if an unadorned `-' argument is passed to us.
2112		 */
2113		while ((optind < argc) && (argv[optind][0] == '-')) {
2114			if (argv[optind][1] != '\0') {
2115				if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
2116					return (S_ERROR);
2117			} else if (++optind < argc)
2118				continue;
2119		}
2120		if (optind >= argc)
2121			break;
2122
2123		path = argv[optind];
2124		if ((fd = open(path, O_RDONLY)) == -1) {
2125			int err = errno;
2126
2127			ld_eprintf(ofl, ERR_FATAL,
2128			    MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
2129			continue;
2130		}
2131
2132		DBG_CALL(Dbg_args_file(ofl->ofl_lml, optind, path));
2133
2134		open_ret = ld_process_open(path, path, &fd, ofl,
2135		    (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej, NULL);
2136		if (fd != -1)
2137			(void) close(fd);
2138		if (open_ret == S_ERROR)
2139			return (S_ERROR);
2140
2141		/*
2142		 * Check for mismatched input.
2143		 */
2144		if (rej.rej_type) {
2145			Conv_reject_desc_buf_t rej_buf;
2146
2147			ld_eprintf(ofl, ERR_FATAL,
2148			    MSG_INTL(reject[rej.rej_type]),
2149			    rej.rej_name ? rej.rej_name :
2150			    MSG_INTL(MSG_STR_UNKNOWN),
2151			    conv_reject_desc(&rej, &rej_buf,
2152			    ld_targ.t_m.m_mach));
2153			return (1);
2154		}
2155	}
2156	return (1);
2157}
2158
2159uintptr_t
2160ld_process_files(Ofl_desc *ofl, int argc, char **argv)
2161{
2162	DBG_CALL(Dbg_basic_files(ofl->ofl_lml));
2163
2164	/*
2165	 * Process command line files (taking into account any applicable
2166	 * preceding flags).  Return if any fatal errors have occurred.
2167	 */
2168	opterr = 0;
2169	optind = 1;
2170	if (process_files_com(ofl, argc, argv) == S_ERROR)
2171		return (S_ERROR);
2172	if (ofl->ofl_flags & FLG_OF_FATAL)
2173		return (1);
2174
2175	/*
2176	 * Guidance: Use -B direct/nodirect or -z direct/nodirect.
2177	 *
2178	 * This is a backstop for the case where the link had no dependencies.
2179	 * Otherwise, it will get caught by ld_process_ifl(). We need both,
2180	 * because -z direct is positional, and its value at the time where
2181	 * the first dependency is seen might be different than it is now.
2182	 */
2183	if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
2184	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
2185		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
2186		ofl->ofl_guideflags |= FLG_OFG_NO_DB;
2187	}
2188
2189	/*
2190	 * Now that all command line files have been processed see if there are
2191	 * any additional `needed' shared object dependencies.
2192	 */
2193	if (ofl->ofl_soneed)
2194		if (ld_finish_libs(ofl) == S_ERROR)
2195			return (S_ERROR);
2196
2197	/*
2198	 * If rescanning archives is enabled, do so now to determine whether
2199	 * there might still be members extracted to satisfy references from any
2200	 * explicit objects.  Continue until no new objects are extracted.  Note
2201	 * that this pass is carried out *after* processing any implicit objects
2202	 * (above) as they may already have resolved any undefined references
2203	 * from any explicit dependencies.
2204	 */
2205	if (ofl->ofl_flags1 & FLG_OF1_RESCAN) {
2206		if (ld_rescan_archives(ofl, 0, argc) == S_ERROR)
2207			return (S_ERROR);
2208		if (ofl->ofl_flags & FLG_OF_FATAL)
2209			return (1);
2210	}
2211
2212	/*
2213	 * If debugging, provide statistics on each archives extraction, or flag
2214	 * any archive that has provided no members.  Note that this could be a
2215	 * nice place to free up much of the archive infrastructure, as we've
2216	 * extracted any members we need.  However, as we presently don't free
2217	 * anything under ld(1) there's not much point in proceeding further.
2218	 */
2219	DBG_CALL(Dbg_statistics_ar(ofl));
2220
2221	/*
2222	 * If any version definitions have been established, either via input
2223	 * from a mapfile or from the input relocatable objects, make sure any
2224	 * version dependencies are satisfied, and version symbols created.
2225	 */
2226	if (ofl->ofl_verdesc)
2227		if (ld_vers_check_defs(ofl) == S_ERROR)
2228			return (S_ERROR);
2229
2230	/*
2231	 * If input section ordering was specified within some segment
2232	 * using a mapfile, verify that the expected sections were seen.
2233	 */
2234	if (ofl->ofl_flags & FLG_OF_IS_ORDER)
2235		ld_ent_check(ofl);
2236
2237	return (1);
2238}
2239
2240uintptr_t
2241ld_init_strings(Ofl_desc *ofl)
2242{
2243	uint_t	stflags;
2244
2245	if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
2246		stflags = 0;
2247	else
2248		stflags = FLG_STNEW_COMPRESS;
2249
2250	if (((ofl->ofl_shdrsttab = st_new(stflags)) == NULL) ||
2251	    ((ofl->ofl_strtab = st_new(stflags)) == NULL) ||
2252	    ((ofl->ofl_dynstrtab = st_new(stflags)) == NULL))
2253		return (S_ERROR);
2254
2255	return (0);
2256}
2257