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