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