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