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