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