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