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