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