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