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