xref: /illumos-gate/usr/src/cmd/sgs/libld/common/args.c (revision c1c6f601cc48d067049ea58a07349897a8e225f2)
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 2006 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 /*
32  * Publically available flags are defined in ld(1).   The following flags are
33  * private, and may be removed at any time.
34  *
35  *    OPTION			MEANING
36  *
37  *    -z dtrace=symbol		assigns symbol to PT_SUNWDTRACE segment,
38  *    				providing scratch ares for dtrace processing.
39  *
40  *    -z noreloc		suppress relocation processing.  This provides
41  *				a mechanism for validating kernel module symbol
42  *				resolution that would normally incur fatal
43  *				relocation errors.
44  *
45  *    -z rtldinfo=symbol	assigns symbol to SUNW_RTLDINF dynamic tag,
46  *				providing pre-initialization specific routines
47  *				for TLS initialization.
48  */
49 #include	<sys/link.h>
50 #include	<stdio.h>
51 #include	<fcntl.h>
52 #include	<string.h>
53 #include	<errno.h>
54 #include	<elf.h>
55 #include	<unistd.h>
56 #include	<debug.h>
57 #include	"msg.h"
58 #include	"_libld.h"
59 
60 /*
61  * Define a set of local argument flags, the settings of these will be
62  * verified in check_flags() and lead to the appropriate output file flags
63  * being initialized.
64  */
65 typedef	enum {
66 	SET_UNKNOWN = -1,
67 	SET_FALSE = 0,
68 	SET_TRUE = 1
69 } Setstate;
70 
71 static Setstate	dflag	= SET_UNKNOWN;
72 static Setstate	zdflag	= SET_UNKNOWN;
73 static Setstate	Qflag	= SET_UNKNOWN;
74 static Setstate	Bdflag	= SET_UNKNOWN;
75 
76 static Boolean	aflag	= FALSE;
77 static Boolean	bflag	= FALSE;
78 static Boolean	rflag	= FALSE;
79 static Boolean	sflag	= FALSE;
80 static Boolean	zinflag = FALSE;
81 static Boolean	zlflag	= FALSE;
82 static Boolean	Bgflag	= FALSE;
83 static Boolean	Blflag	= FALSE;
84 static Boolean	Beflag	= FALSE;
85 static Boolean	Bsflag	= FALSE;
86 static Boolean	Btflag	= FALSE;
87 static Boolean	Gflag	= FALSE;
88 static Boolean	Vflag	= FALSE;
89 
90 /*
91  * ztflag's state is set by pointing it to the matching string:
92  *	text | textoff | textwarn
93  */
94 static const char	*ztflag = 0;
95 
96 static uintptr_t process_files_com(Ofl_desc *, int, char **);
97 static uintptr_t process_flags_com(Ofl_desc *, int, char **, int *);
98 
99 /*
100  * Print usage message to stderr - 2 modes, summary message only,
101  * and full usage message.
102  */
103 static void
104 usage_mesg(Boolean detail)
105 {
106 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_USAGE),
107 	    MSG_ORIG(MSG_STR_OPTIONS));
108 
109 	if (detail == FALSE)
110 		return;
111 
112 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_6));
113 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_A));
114 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_B));
115 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDR));
116 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDY));
117 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBE));
118 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBG));
119 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBL));
120 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBR));
121 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBS));
122 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_C));
123 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CC));
124 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_D));
125 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CD));
126 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_E));
127 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_F));
128 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CF));
129 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CG));
130 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_H));
131 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_I));
132 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CI));
133 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_L));
134 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CL));
135 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_M));
136 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CM));
137 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CN));
138 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_O));
139 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_P));
140 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CP));
141 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CQ));
142 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_R));
143 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CR));
144 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_S));
145 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CS));
146 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_T));
147 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_U));
148 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CV));
149 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY));
150 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA));
151 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
152 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
153 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNC));
154 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
155 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
156 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
157 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFA));
158 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGP));
159 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZH));
160 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZIG));
161 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINA));
162 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINI));
163 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINT));
164 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLAZY));
165 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD32));
166 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD64));
167 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLO));
168 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZM));
169 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDFS));
170 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEF));
171 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEL));
172 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDLO));
173 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDU));
174 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNPA));
175 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNV));
176 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNOW));
177 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZO));
178 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZPIA));
179 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRL));
180 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRS));
181 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT));
182 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO));
183 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW));
184 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZV));
185 }
186 
187 /*
188  * Checks the command line option flags for consistency.
189  */
190 static uintptr_t
191 check_flags(Ofl_desc * ofl, int argc)
192 {
193 	if (Plibpath && (Llibdir || Ulibdir)) {
194 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
195 		    Llibdir ? 'L' : 'U');
196 		ofl->ofl_flags |= FLG_OF_FATAL;
197 	}
198 
199 	if (rflag) {
200 		if (dflag == SET_UNKNOWN)
201 			dflag = SET_FALSE;
202 		if (ofl->ofl_flags1 & FLG_OF1_RELCNT) {
203 			eprintf(ofl->ofl_lml, ERR_WARNING,
204 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_R),
205 			    MSG_ORIG(MSG_ARG_ZCOMBRELOC));
206 			ofl->ofl_flags1 &= ~FLG_OF1_RELCNT;
207 		}
208 		ofl->ofl_flags |= FLG_OF_RELOBJ;
209 	}
210 
211 	if (zdflag == SET_TRUE)
212 		ofl->ofl_flags |= FLG_OF_NOUNDEF;
213 
214 	if (zinflag)
215 		ofl->ofl_dtflags_1 |= DF_1_INTERPOSE;
216 
217 	if (sflag)
218 		ofl->ofl_flags |= FLG_OF_STRIP;
219 
220 	if (Qflag == SET_TRUE)
221 		ofl->ofl_flags |= FLG_OF_ADDVERS;
222 
223 	if (Blflag)
224 		ofl->ofl_flags |= FLG_OF_AUTOLCL;
225 
226 	if (Beflag)
227 		ofl->ofl_flags1 |= FLG_OF1_AUTOELM;
228 
229 	if (Blflag && Beflag) {
230 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
231 		    MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL));
232 		ofl->ofl_flags |= FLG_OF_FATAL;
233 	}
234 
235 	if (dflag != SET_FALSE) {
236 		/*
237 		 * Set -Bdynamic on by default, setting is rechecked as input
238 		 * files are processed.
239 		 */
240 		ofl->ofl_flags |=
241 		    (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED);
242 
243 		if (aflag) {
244 			eprintf(ofl->ofl_lml, ERR_FATAL,
245 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DY),
246 			    MSG_ORIG(MSG_ARG_A));
247 			ofl->ofl_flags |= FLG_OF_FATAL;
248 		}
249 
250 		if (bflag)
251 			ofl->ofl_flags |= FLG_OF_BFLAG;
252 
253 		if (Bgflag == TRUE) {
254 			if (zdflag == SET_FALSE) {
255 				eprintf(ofl->ofl_lml, ERR_FATAL,
256 				    MSG_INTL(MSG_ARG_INCOMP),
257 				    MSG_ORIG(MSG_ARG_BGROUP),
258 				    MSG_ORIG(MSG_ARG_ZNODEF));
259 				ofl->ofl_flags |= FLG_OF_FATAL;
260 			}
261 			ofl->ofl_dtflags_1 |= DF_1_GROUP;
262 			ofl->ofl_flags |= FLG_OF_NOUNDEF;
263 		}
264 
265 		/*
266 		 * If the use of default library searching has been suppressed
267 		 * but no runpaths have been provided we're going to have a hard
268 		 * job running this object.
269 		 */
270 		if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath)
271 			eprintf(ofl->ofl_lml, ERR_WARNING,
272 			    MSG_INTL(MSG_ARG_NODEFLIB));
273 
274 		/*
275 		 * By default, text relocation warnings are given when building
276 		 * an executable unless the -b flag is specified.  This option
277 		 * implies that unclean text can be created, so no warnings are
278 		 * generated unless specifically asked for.
279 		 */
280 		if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) ||
281 		    ((ztflag == 0) && bflag))
282 			ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
283 		else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT))
284 			ofl->ofl_flags |= FLG_OF_PURETXT;
285 
286 		if (Gflag || !rflag) {
287 			/*
288 			 * Create a dynamic object.  -Bdirect indicates that all
289 			 * references should be bound directly.  This also
290 			 * enables lazyloading.  Individual symbols can be
291 			 * bound directly (or not) using mapfiles and the
292 			 * DIRECT (NODIRECT) qualifier.  With this capability,
293 			 * each syminfo entry is tagged SYMINFO_FLG_DIRECTBIND.
294 			 * Prior to this per-symbol direct binding, runtime
295 			 * direct binding was controlled via the DF_1_DIRECT
296 			 * flag.  This flag affected all references from the
297 			 * object.  -Bdirect continues to set this flag, and
298 			 * thus provides a means of taking a newly built
299 			 * direct binding object back to older systems.
300 			 *
301 			 * NOTE, any use of per-symbol NODIRECT bindings, or
302 			 * -znodirect, will disable the creation of the
303 			 * DF_1_DIRECT flag.  Older runtime linkers do not
304 			 * have the capability to do per-symbol direct bindings.
305 			 */
306 			if (Bdflag == SET_TRUE) {
307 				ofl->ofl_dtflags_1 |= DF_1_DIRECT;
308 				ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
309 				ofl->ofl_flags |= FLG_OF_SYMINFO;
310 			}
311 
312 			/*
313 			 * -Bnodirect disables directly binding to any symbols
314 			 * exported from the object being created.  Individual
315 			 * references to external objects can still be affected
316 			 * by -zdirect or mapfile DIRECT directives.
317 			 */
318 			if (Bdflag == SET_FALSE) {
319 				ofl->ofl_dtflags_1 |= DF_1_NODIRECT;
320 				ofl->ofl_flags1 |=
321 				    (FLG_OF1_NDIRECT | FLG_OF1_ALNODIR);
322 				ofl->ofl_flags |= FLG_OF_SYMINFO;
323 			}
324 		}
325 
326 		if (!Gflag && !rflag) {
327 			/*
328 			 * Dynamically linked executable.
329 			 */
330 			ofl->ofl_flags |= FLG_OF_EXEC;
331 
332 			if (zdflag != SET_FALSE)
333 				ofl->ofl_flags |= FLG_OF_NOUNDEF;
334 
335 			if (Bsflag) {
336 				eprintf(ofl->ofl_lml, ERR_FATAL,
337 				    MSG_INTL(MSG_ARG_DYNINCOMP),
338 				    MSG_ORIG(MSG_ARG_BSYMBOLIC));
339 				ofl->ofl_flags |= FLG_OF_FATAL;
340 			}
341 			if (ofl->ofl_soname) {
342 				eprintf(ofl->ofl_lml, ERR_FATAL,
343 				    MSG_INTL(MSG_ARG_DYNINCOMP),
344 				    MSG_ORIG(MSG_ARG_H));
345 				ofl->ofl_flags |= FLG_OF_FATAL;
346 			}
347 			if (Btflag) {
348 				eprintf(ofl->ofl_lml, ERR_FATAL,
349 				    MSG_INTL(MSG_ARG_DYNINCOMP),
350 				    MSG_ORIG(MSG_ARG_BTRANS));
351 				ofl->ofl_flags |= FLG_OF_FATAL;
352 			}
353 			if (ofl->ofl_filtees) {
354 				if (ofl->ofl_flags & FLG_OF_AUX) {
355 					eprintf(ofl->ofl_lml, ERR_FATAL,
356 					    MSG_INTL(MSG_ARG_DYNINCOMP),
357 					    MSG_ORIG(MSG_ARG_F));
358 				} else {
359 					eprintf(ofl->ofl_lml, ERR_FATAL,
360 					    MSG_INTL(MSG_ARG_DYNINCOMP),
361 					    MSG_ORIG(MSG_ARG_CF));
362 				}
363 				ofl->ofl_flags |= FLG_OF_FATAL;
364 			}
365 
366 		} else if (!rflag) {
367 			/*
368 			 * Shared library.
369 			 */
370 			ofl->ofl_flags |= FLG_OF_SHAROBJ;
371 
372 			/*
373 			 * By default we print relocation errors for
374 			 * executables but *not* for a shared object
375 			 */
376 			if (ztflag == 0)
377 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
378 
379 			if (Bsflag) {
380 				ofl->ofl_flags |= FLG_OF_SYMBOLIC;
381 				ofl->ofl_dtflags |= DF_SYMBOLIC;
382 			}
383 
384 			if (Btflag) {
385 				ofl->ofl_dtflags_1 |=
386 				    (DF_1_TRANS | DF_1_DIRECT);
387 				ofl->ofl_flags |= FLG_OF_SYMINFO;
388 			}
389 
390 		} else {
391 			/*
392 			 * Dynamic relocatable object
393 			 */
394 			/*
395 			 * By default we print relocation errors for
396 			 * executables but *not* for a shared object
397 			 */
398 			if (ztflag == 0)
399 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
400 		}
401 	} else {
402 		ofl->ofl_flags |= FLG_OF_STATIC;
403 
404 		if (bflag) {
405 			eprintf(ofl->ofl_lml, ERR_FATAL,
406 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
407 			    MSG_ORIG(MSG_ARG_B));
408 			ofl->ofl_flags |= FLG_OF_FATAL;
409 		}
410 		if (ofl->ofl_soname) {
411 			eprintf(ofl->ofl_lml, ERR_FATAL,
412 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
413 			    MSG_ORIG(MSG_ARG_H));
414 			ofl->ofl_flags |= FLG_OF_FATAL;
415 		}
416 		if (ofl->ofl_depaudit) {
417 			eprintf(ofl->ofl_lml, ERR_FATAL,
418 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
419 			    MSG_ORIG(MSG_ARG_P));
420 			ofl->ofl_flags |= FLG_OF_FATAL;
421 		}
422 		if (ofl->ofl_audit) {
423 			eprintf(ofl->ofl_lml, ERR_FATAL,
424 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
425 			    MSG_ORIG(MSG_ARG_CP));
426 			ofl->ofl_flags |= FLG_OF_FATAL;
427 		}
428 		if (ofl->ofl_config) {
429 			eprintf(ofl->ofl_lml, ERR_FATAL,
430 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
431 			    MSG_ORIG(MSG_ARG_C));
432 			ofl->ofl_flags |= FLG_OF_FATAL;
433 		}
434 		if (ofl->ofl_filtees) {
435 			if (ofl->ofl_flags & FLG_OF_AUX) {
436 				eprintf(ofl->ofl_lml, ERR_FATAL,
437 				    MSG_INTL(MSG_ARG_INCOMP),
438 				    MSG_ORIG(MSG_ARG_DN), MSG_ORIG(MSG_ARG_F));
439 			} else {
440 				eprintf(ofl->ofl_lml, ERR_FATAL,
441 				    MSG_INTL(MSG_ARG_INCOMP),
442 				    MSG_ORIG(MSG_ARG_DN), MSG_ORIG(MSG_ARG_CF));
443 			}
444 			ofl->ofl_flags |= FLG_OF_FATAL;
445 		}
446 		if (ztflag) {
447 			eprintf(ofl->ofl_lml, ERR_FATAL,
448 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
449 			    MSG_ORIG(MSG_ARG_ZTEXTALL));
450 			ofl->ofl_flags |= FLG_OF_FATAL;
451 		}
452 		if (Gflag) {
453 			eprintf(ofl->ofl_lml, ERR_FATAL,
454 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN),
455 			    MSG_ORIG(MSG_ARG_CG));
456 			ofl->ofl_flags |= FLG_OF_FATAL;
457 		}
458 		if (aflag && rflag) {
459 			eprintf(ofl->ofl_lml, ERR_FATAL,
460 			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_A),
461 			    MSG_ORIG(MSG_ARG_R));
462 			ofl->ofl_flags |= FLG_OF_FATAL;
463 		}
464 
465 		if (rflag) {
466 			/*
467 			 * We can only strip the symbol table and string table
468 			 * if no output relocations will refer to them
469 			 */
470 			if (sflag) {
471 				eprintf(ofl->ofl_lml, ERR_WARNING,
472 				    MSG_INTL(MSG_ARG_STRIP));
473 			}
474 
475 			if (ztflag == 0)
476 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
477 
478 			if (ofl->ofl_interp) {
479 				eprintf(ofl->ofl_lml, ERR_FATAL,
480 				    MSG_INTL(MSG_ARG_INCOMP),
481 				    MSG_ORIG(MSG_ARG_R), MSG_ORIG(MSG_ARG_CI));
482 				ofl->ofl_flags |= FLG_OF_FATAL;
483 			}
484 		} else {
485 			/*
486 			 * Static executable.
487 			 */
488 			ofl->ofl_flags |= FLG_OF_EXEC | FLG_OF_PROCRED;
489 
490 			if (zdflag != SET_FALSE)
491 				ofl->ofl_flags |= FLG_OF_NOUNDEF;
492 		}
493 	}
494 
495 	/*
496 	 * If the user didn't supply an output file name supply a default.
497 	 */
498 	if (ofl->ofl_name == NULL)
499 		ofl->ofl_name = MSG_ORIG(MSG_STR_AOUT);
500 
501 	/*
502 	 * We set the entrance criteria after all input argument processing as
503 	 * it is only at this point we're sure what the output image will be
504 	 * (static or dynamic).
505 	 */
506 	if (ld_ent_setup(ofl, M_SEGM_ALIGN) == S_ERROR)
507 		return (S_ERROR);
508 
509 	/*
510 	 * Initialize string tables.  Symbol definitions within mapfiles can
511 	 * result in the creation of input sections.
512 	 */
513 	if (ld_init_strings(ofl) == S_ERROR)
514 		return (S_ERROR);
515 
516 	/*
517 	 * Process any mapfiles after establishing the entrance criteria as
518 	 * the user may be redefining or adding sections/segments.
519 	 */
520 	if (ofl->ofl_maps.head) {
521 		Listnode	*lnp;
522 		const char	*name;
523 
524 		for (LIST_TRAVERSE(&ofl->ofl_maps, lnp, name))
525 			if (ld_map_parse(name, ofl) == S_ERROR)
526 				return (S_ERROR);
527 
528 		if (ofl->ofl_flags & FLG_OF_SEGSORT)
529 			if (ld_sort_seg_list(ofl) == S_ERROR)
530 				return (S_ERROR);
531 	}
532 
533 	/*
534 	 * If -zloadfltr is set, verify that filtering is in effect.  Filters
535 	 * are either established from the command line, and affect the whole
536 	 * object, or are set on a per-symbol basis from a mapfile.
537 	 */
538 	if (zlflag) {
539 		if ((ofl->ofl_filtees == 0) && (ofl->ofl_dtsfltrs == 0)) {
540 			eprintf(ofl->ofl_lml, ERR_FATAL,
541 			    MSG_INTL(MSG_ARG_NOFLTR),
542 			    MSG_ORIG(MSG_ARG_ZLOADFLTR));
543 			ofl->ofl_flags |= FLG_OF_FATAL;
544 		}
545 		ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
546 	}
547 
548 	/*
549 	 * Check that we have something to work with.  This check is carried out
550 	 * after mapfile processing as its possible a mapfile is being used to
551 	 * define symbols, in which case it would be sufficient to build the
552 	 * output file purely from the mapfile.
553 	 */
554 	if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
555 		if (Vflag && (argc == 2))
556 			ofl->ofl_flags1 |= FLG_OF1_DONE;
557 		else {
558 			eprintf(ofl->ofl_lml, ERR_FATAL,
559 			    MSG_INTL(MSG_ARG_NOFILES));
560 			return (S_ERROR);
561 		}
562 	}
563 	return (1);
564 }
565 
566 /*
567  * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
568  * used as an argument to getopt().
569  *
570  * If the second argument 'error' is not 0, then this is called from the first
571  * pass. Else this is called from the second pass.
572  */
573 static uintptr_t
574 createargv(Ofl_desc *ofl, int *error)
575 {
576 	int		argc = 0, idx = 0, ooptind;
577 	uintptr_t	ret;
578 	char		**argv, *p0;
579 
580 	/*
581 	 * The argument being examined is either:
582 	 *	ld32= 	or
583 	 *	ld64=
584 	 */
585 #if	defined(_LP64)
586 	if (optarg[2] == '3')
587 		return (0);
588 #else
589 	if (optarg[2] == '6')
590 		return (0);
591 #endif
592 
593 	p0 = &optarg[5];
594 
595 	/*
596 	 * Count the number of arguments.
597 	 */
598 	while (*p0) {
599 		/*
600 		 * Pointing at non-separator character.
601 		 */
602 		if (*p0 != ',') {
603 			argc++;
604 			while (*p0 && (*p0 != ','))
605 				p0++;
606 			continue;
607 		}
608 
609 		/*
610 		 * Pointing at a separator character.
611 		 */
612 		if (*p0 == ',') {
613 			while (*p0 == ',')
614 				p0++;
615 			continue;
616 		}
617 	}
618 
619 	if (argc == 0)
620 		return (0);
621 
622 	/*
623 	 * Allocate argument vector.
624 	 */
625 	if ((p0 = (char *)strdup(&optarg[5])) == 0)
626 		return (S_ERROR);
627 	if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == 0)
628 		return (S_ERROR);
629 
630 	while (*p0) {
631 		char *p;
632 
633 		/*
634 		 * Pointing at the beginning of non-separator character string.
635 		 */
636 		if (*p0 != ',') {
637 			p = p0;
638 			while (*p0 && (*p0 != ','))
639 				p0++;
640 			argv[idx++] = p;
641 			if (*p0) {
642 				*p0 = '\0';
643 				p0++;
644 			}
645 			continue;
646 		}
647 
648 		/*
649 		 * Pointing at the beginining of separator character string.
650 		 */
651 		if (*p0 == ',') {
652 			while (*p0 == ',')
653 				p0++;
654 			continue;
655 		}
656 	}
657 	argv[idx] = 0;
658 	ooptind = optind;
659 	optind = 0;
660 
661 	/*
662 	 * Dispatch to pass1 or pass2
663 	 */
664 	if (error)
665 		ret = process_flags_com(ofl, argc, argv, error);
666 	else
667 		ret = process_files_com(ofl, argc, argv);
668 
669 	optind = ooptind;
670 
671 	if (ret == S_ERROR)
672 		return (S_ERROR);
673 
674 	return (argc);
675 }
676 
677 /*
678  * Parsing options pass1 for process_flags().
679  */
680 static uintptr_t
681 parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *error)
682 {
683 	int	c;
684 
685 	while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
686 		DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c));
687 
688 		switch (c) {
689 		case '6':			/* Processed by ld to */
690 			/*
691 			 * -64 is processed by ld to determine the output class.
692 			 * Here we sanity check the option incase some other
693 			 * -6* option is mistakenly passed to us.
694 			 */
695 			if (optarg[0] != '4') {
696 				eprintf(ofl->ofl_lml, ERR_FATAL,
697 				    MSG_INTL(MSG_ARG_ILLEGAL),
698 				    MSG_ORIG(MSG_ARG_6), optarg);
699 				ofl->ofl_flags |= FLG_OF_FATAL;
700 			}
701 			continue;
702 
703 		case 'a':
704 			aflag = TRUE;
705 			break;
706 
707 		case 'b':
708 			bflag = TRUE;
709 			break;
710 
711 		case 'c':
712 			if (ofl->ofl_config)
713 				eprintf(ofl->ofl_lml, ERR_WARNING,
714 				    MSG_INTL(MSG_ARG_MTONCE),
715 				    MSG_ORIG(MSG_ARG_C));
716 			else
717 				ofl->ofl_config = optarg;
718 			break;
719 
720 		case 'C':
721 			demangle_flag = 1;
722 			break;
723 
724 		case 'd':
725 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
726 				if (dflag != SET_UNKNOWN)
727 					eprintf(ofl->ofl_lml, ERR_WARNING,
728 					    MSG_INTL(MSG_ARG_MTONCE),
729 					    MSG_ORIG(MSG_ARG_D));
730 				else
731 					dflag = SET_FALSE;
732 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
733 				if (dflag != SET_UNKNOWN)
734 					eprintf(ofl->ofl_lml, ERR_WARNING,
735 					    MSG_INTL(MSG_ARG_MTONCE),
736 					    MSG_ORIG(MSG_ARG_D));
737 				else
738 					dflag = SET_TRUE;
739 			} else {
740 				eprintf(ofl->ofl_lml, ERR_FATAL,
741 				    MSG_INTL(MSG_ARG_ILLEGAL),
742 				    MSG_ORIG(MSG_ARG_D), optarg);
743 				ofl->ofl_flags |= FLG_OF_FATAL;
744 			}
745 			break;
746 
747 		case 'e':
748 			if (ofl->ofl_entry)
749 				eprintf(ofl->ofl_lml, ERR_WARNING,
750 				    MSG_INTL(MSG_ARG_MTONCE),
751 				    MSG_ORIG(MSG_ARG_E));
752 			else
753 				ofl->ofl_entry = (void *)optarg;
754 			break;
755 
756 		case 'f':
757 			if (ofl->ofl_filtees &&
758 			    (!(ofl->ofl_flags & FLG_OF_AUX))) {
759 				eprintf(ofl->ofl_lml, ERR_FATAL,
760 				    MSG_INTL(MSG_ARG_INCOMP),
761 				    MSG_ORIG(MSG_ARG_F), MSG_ORIG(MSG_ARG_CF));
762 				ofl->ofl_flags |= FLG_OF_FATAL;
763 			} else {
764 				if ((ofl->ofl_filtees =
765 				    add_string(ofl->ofl_filtees, optarg)) ==
766 				    (const char *)S_ERROR)
767 					return (S_ERROR);
768 				ofl->ofl_flags |= FLG_OF_AUX;
769 			}
770 			break;
771 
772 		case 'F':
773 			if (ofl->ofl_filtees &&
774 			    (ofl->ofl_flags & FLG_OF_AUX)) {
775 				eprintf(ofl->ofl_lml, ERR_FATAL,
776 				    MSG_INTL(MSG_ARG_INCOMP),
777 				    MSG_ORIG(MSG_ARG_CF), MSG_ORIG(MSG_ARG_F));
778 				ofl->ofl_flags |= FLG_OF_FATAL;
779 			} else {
780 				if ((ofl->ofl_filtees =
781 				    add_string(ofl->ofl_filtees, optarg)) ==
782 				    (const char *)S_ERROR)
783 					return (S_ERROR);
784 			}
785 			break;
786 
787 		case 'h':
788 			if (ofl->ofl_soname)
789 				eprintf(ofl->ofl_lml, ERR_WARNING,
790 				    MSG_INTL(MSG_ARG_MTONCE),
791 				    MSG_ORIG(MSG_ARG_H));
792 			else
793 				ofl->ofl_soname = (const char *)optarg;
794 			break;
795 
796 		case 'i':
797 			ofl->ofl_flags |= FLG_OF_IGNENV;
798 			break;
799 
800 		case 'I':
801 			if (ofl->ofl_interp)
802 				eprintf(ofl->ofl_lml, ERR_WARNING,
803 				    MSG_INTL(MSG_ARG_MTONCE),
804 				    MSG_ORIG(MSG_ARG_CI));
805 			else
806 				ofl->ofl_interp = (const char *)optarg;
807 			break;
808 
809 		case 'l':
810 			/*
811 			 * For now, count any library as a shared object.  This
812 			 * is used to size the internal symbol cache.  This
813 			 * value is recalculated later on actual file processing
814 			 * to get an accurate shared object count.
815 			 */
816 			ofl->ofl_soscnt++;
817 			break;
818 
819 		case 'm':
820 			ofl->ofl_flags |= FLG_OF_GENMAP;
821 			break;
822 
823 		case 'o':
824 			if (ofl->ofl_name)
825 				eprintf(ofl->ofl_lml, ERR_WARNING,
826 				    MSG_INTL(MSG_ARG_MTONCE),
827 				    MSG_ORIG(MSG_ARG_O));
828 			else
829 				ofl->ofl_name = (const char *)optarg;
830 			break;
831 
832 		case 'p':
833 			/*
834 			 * Multiple instances of this option may occur.  Each
835 			 * additional instance is effectively concatenated to
836 			 * the previous separated by a colon.
837 			 */
838 			if (*optarg != '\0') {
839 				if ((ofl->ofl_audit =
840 				    add_string(ofl->ofl_audit,
841 				    optarg)) == (const char *)S_ERROR)
842 					return (S_ERROR);
843 			}
844 			break;
845 
846 		case 'P':
847 			/*
848 			 * Multiple instances of this option may occur.  Each
849 			 * additional instance is effectively concatenated to
850 			 * the previous separated by a colon.
851 			 */
852 			if (*optarg != '\0') {
853 				if ((ofl->ofl_depaudit =
854 				    add_string(ofl->ofl_depaudit,
855 				    optarg)) == (const char *)S_ERROR)
856 					return (S_ERROR);
857 			}
858 			break;
859 
860 		case 'r':
861 			rflag = TRUE;
862 			break;
863 
864 		case 'R':
865 			/*
866 			 * Multiple instances of this option may occur.  Each
867 			 * additional instance is effectively concatenated to
868 			 * the previous separated by a colon.
869 			 */
870 			if (*optarg != '\0') {
871 				if ((ofl->ofl_rpath =
872 				    add_string(ofl->ofl_rpath,
873 				    optarg)) == (const char *)S_ERROR)
874 					return (S_ERROR);
875 			}
876 			break;
877 
878 		case 's':
879 			sflag = TRUE;
880 			break;
881 
882 		case 't':
883 			ofl->ofl_flags |= FLG_OF_NOWARN;
884 			break;
885 
886 		case 'u':
887 			break;
888 
889 		case 'z':
890 			/*
891 			 * For specific help, print our usage message and exit
892 			 * immediately to insure a 0 return code.
893 			 */
894 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
895 			    MSG_ARG_HELP_SIZE) == 0) {
896 				usage_mesg(1);
897 				exit(0);
898 			}
899 
900 			/*
901 			 * For some options set a flag - further consistancy
902 			 * checks will be carried out in check_flags().
903 			 */
904 			if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
905 			    MSG_ARG_LD32_SIZE) == 0) ||
906 			    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
907 			    MSG_ARG_LD64_SIZE) == 0)) {
908 				if (createargv(ofl, error) == S_ERROR)
909 					return (S_ERROR);
910 
911 			} else if (
912 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
913 				if (zdflag != SET_UNKNOWN)
914 					eprintf(ofl->ofl_lml, ERR_WARNING,
915 					    MSG_INTL(MSG_ARG_MTONCE),
916 					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
917 				else
918 					zdflag = SET_TRUE;
919 			} else if (strcmp(optarg,
920 			    MSG_ORIG(MSG_ARG_NODEFS)) == 0) {
921 				if (zdflag != SET_UNKNOWN)
922 					eprintf(ofl->ofl_lml, ERR_WARNING,
923 					    MSG_INTL(MSG_ARG_MTONCE),
924 					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
925 				else
926 					zdflag = SET_FALSE;
927 			} else if (strcmp(optarg,
928 			    MSG_ORIG(MSG_ARG_TEXT)) == 0) {
929 				if (ztflag &&
930 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT))) {
931 					eprintf(ofl->ofl_lml, ERR_FATAL,
932 					    MSG_INTL(MSG_ARG_INCOMP),
933 					    MSG_ORIG(MSG_ARG_ZTEXT),
934 					    ztflag);
935 					ofl->ofl_flags |= FLG_OF_FATAL;
936 				}
937 				ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
938 			} else if (strcmp(optarg,
939 			    MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
940 				if (ztflag &&
941 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF))) {
942 					eprintf(ofl->ofl_lml, ERR_FATAL,
943 					    MSG_INTL(MSG_ARG_INCOMP),
944 					    MSG_ORIG(MSG_ARG_ZTEXTOFF),
945 					    ztflag);
946 					ofl->ofl_flags |= FLG_OF_FATAL;
947 				}
948 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
949 			} else if (strcmp(optarg,
950 			    MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
951 				if (ztflag &&
952 				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN))) {
953 					eprintf(ofl->ofl_lml, ERR_FATAL,
954 					    MSG_INTL(MSG_ARG_INCOMP),
955 					    MSG_ORIG(MSG_ARG_ZTEXTWARN),
956 					    ztflag);
957 					ofl->ofl_flags |= FLG_OF_FATAL;
958 				}
959 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
960 
961 			/*
962 			 * For other options simply set the ofl flags directly.
963 			 */
964 			} else if (strcmp(optarg,
965 			    MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
966 				ofl->ofl_flags1 |= FLG_OF1_RESCAN;
967 			} else if (strcmp(optarg,
968 			    MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
969 				ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
970 			} else if (strcmp(optarg,
971 			    MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
972 				zlflag = TRUE;
973 			} else if (strcmp(optarg,
974 			    MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
975 				ofl->ofl_dtflags_1 |= DF_1_NORELOC;
976 			} else if (strcmp(optarg,
977 			    MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
978 				ofl->ofl_flags |= FLG_OF_NOVERSEC;
979 			} else if (strcmp(optarg,
980 			    MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
981 				ofl->ofl_flags |= FLG_OF_MULDEFS;
982 			} else if (strcmp(optarg,
983 			    MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
984 				ofl->ofl_flags1 |= FLG_OF1_REDLSYM;
985 			} else if (strcmp(optarg,
986 			    MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
987 				ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
988 			} else if (strcmp(optarg,
989 			    MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
990 				ofl->ofl_dtflags_1 |= DF_1_NODELETE;
991 			} else if (strcmp(optarg,
992 			    MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
993 				ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
994 			} else if (strcmp(optarg,
995 			    MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
996 				ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
997 			} else if (strcmp(optarg,
998 			    MSG_ORIG(MSG_ARG_NOW)) == 0) {
999 				ofl->ofl_dtflags_1 |= DF_1_NOW;
1000 				ofl->ofl_dtflags |= DF_BIND_NOW;
1001 			} else if (strcmp(optarg,
1002 			    MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
1003 				ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
1004 				ofl->ofl_dtflags |= DF_ORIGIN;
1005 			} else if (strcmp(optarg,
1006 			    MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1007 				ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1008 			} else if (strcmp(optarg,
1009 			    MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1010 				ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1011 			} else if (strcmp(optarg,
1012 			    MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1013 				ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1014 			} else if (strcmp(optarg,
1015 			    MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1016 				ofl->ofl_flags |= FLG_OF_VERBOSE;
1017 			} else if (strcmp(optarg,
1018 			    MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1019 				ofl->ofl_flags1 |= FLG_OF1_RELCNT;
1020 			} else if (strcmp(optarg,
1021 			    MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1022 				ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1023 			} else if (strcmp(optarg,
1024 			    MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1025 				zinflag = TRUE;
1026 			} else if (strcmp(optarg,
1027 			    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1028 				ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1029 
1030 			/*
1031 			 * The following options just need validation as they
1032 			 * are interpreted on the second pass through the
1033 			 * command line arguments.
1034 			 */
1035 			} else if (
1036 			    strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1037 				MSG_ARG_INITARRAY_SIZE) &&
1038 			    strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1039 				MSG_ARG_FINIARRAY_SIZE) &&
1040 			    strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1041 				MSG_ARG_PREINITARRAY_SIZE) &&
1042 			    strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1043 				MSG_ARG_RTLDINFO_SIZE) &&
1044 			    strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1045 				MSG_ARG_DTRACE_SIZE) &&
1046 			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1047 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1048 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1049 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1050 			    strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1051 			    strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1052 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1053 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1054 			    strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1055 			    strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT))) {
1056 				eprintf(ofl->ofl_lml, ERR_FATAL,
1057 				    MSG_INTL(MSG_ARG_ILLEGAL),
1058 				    MSG_ORIG(MSG_ARG_Z), optarg);
1059 				ofl->ofl_flags |= FLG_OF_FATAL;
1060 
1061 			}
1062 
1063 			break;
1064 
1065 		case 'D':
1066 			/*
1067 			 * If we have not yet read any input files go ahead
1068 			 * and process any debugging options (this allows any
1069 			 * argument processing, entrance criteria and library
1070 			 * initialization to be displayed).  Otherwise, if an
1071 			 * input file has been seen, skip interpretation until
1072 			 * process_files (this allows debugging to be turned
1073 			 * on and off around individual groups of files).
1074 			 */
1075 			if (ofl->ofl_objscnt == 0) {
1076 				if (dbg_setup(optarg, dbg_desc,
1077 				    &ofl->ofl_name, 1) == S_ERROR)
1078 					return (S_ERROR);
1079 			}
1080 			break;
1081 
1082 		case 'B':
1083 			if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1084 				if (Bdflag == SET_FALSE) {
1085 					eprintf(ofl->ofl_lml, ERR_FATAL,
1086 					    MSG_INTL(MSG_ARG_INCOMP),
1087 					    MSG_ORIG(MSG_ARG_BNODIRECT),
1088 					    MSG_ORIG(MSG_ARG_BDIRECT));
1089 					ofl->ofl_flags |= FLG_OF_FATAL;
1090 				} else
1091 					Bdflag = SET_TRUE;
1092 			} else if (strcmp(optarg,
1093 			    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1094 				if (Bdflag == SET_TRUE) {
1095 					eprintf(ofl->ofl_lml, ERR_FATAL,
1096 					    MSG_INTL(MSG_ARG_INCOMP),
1097 					    MSG_ORIG(MSG_ARG_BDIRECT),
1098 					    MSG_ORIG(MSG_ARG_BNODIRECT));
1099 					ofl->ofl_flags |= FLG_OF_FATAL;
1100 				} else
1101 					Bdflag = SET_FALSE;
1102 			} else if (strcmp(optarg,
1103 			    MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1104 				Bsflag = TRUE;
1105 			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1106 				ofl->ofl_flags |= FLG_OF_PROCRED;
1107 			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1108 				Blflag = TRUE;
1109 			else if (strcmp(optarg,
1110 			    MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0)
1111 				Btflag = TRUE;
1112 			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1113 				Bgflag = TRUE;
1114 			else if (strcmp(optarg,
1115 			    MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1116 				Beflag = TRUE;
1117 			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1118 			    strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1119 				eprintf(ofl->ofl_lml, ERR_FATAL,
1120 				    MSG_INTL(MSG_ARG_ILLEGAL),
1121 				    MSG_ORIG(MSG_ARG_CB), optarg);
1122 				ofl->ofl_flags |= FLG_OF_FATAL;
1123 			}
1124 			break;
1125 
1126 		case 'G':
1127 			Gflag = TRUE;
1128 			break;
1129 
1130 		case 'L':
1131 			break;
1132 
1133 		case 'M':
1134 			if (list_appendc(&(ofl->ofl_maps), optarg) == 0)
1135 				return (S_ERROR);
1136 			break;
1137 
1138 		case 'N':
1139 			break;
1140 
1141 		case 'Q':
1142 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1143 				if (Qflag != SET_UNKNOWN)
1144 					eprintf(ofl->ofl_lml, ERR_WARNING,
1145 					    MSG_INTL(MSG_ARG_MTONCE),
1146 					    MSG_ORIG(MSG_ARG_CQ));
1147 				else
1148 					Qflag = SET_FALSE;
1149 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1150 				if (Qflag != SET_UNKNOWN)
1151 					eprintf(ofl->ofl_lml, ERR_WARNING,
1152 					    MSG_INTL(MSG_ARG_MTONCE),
1153 					    MSG_ORIG(MSG_ARG_CQ));
1154 				else
1155 					Qflag = SET_TRUE;
1156 			} else {
1157 				eprintf(ofl->ofl_lml, ERR_FATAL,
1158 				    MSG_INTL(MSG_ARG_ILLEGAL),
1159 				    MSG_ORIG(MSG_ARG_CQ), optarg);
1160 				ofl->ofl_flags |= FLG_OF_FATAL;
1161 			}
1162 			break;
1163 
1164 		case 'S':
1165 			if (list_appendc(&lib_support, optarg) == 0)
1166 				return (S_ERROR);
1167 			break;
1168 
1169 		case 'V':
1170 			if (!Vflag)
1171 				(void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1172 				    ofl->ofl_sgsid);
1173 			Vflag = TRUE;
1174 			break;
1175 
1176 		case 'Y':
1177 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1178 				if (Llibdir)
1179 				    eprintf(ofl->ofl_lml, ERR_WARNING,
1180 					MSG_INTL(MSG_ARG_MTONCE),
1181 					MSG_ORIG(MSG_ARG_CYL));
1182 				else
1183 					Llibdir = optarg + 2;
1184 			} else if (strncmp(optarg,
1185 			    MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1186 				if (Ulibdir)
1187 					eprintf(ofl->ofl_lml, ERR_WARNING,
1188 					    MSG_INTL(MSG_ARG_MTONCE),
1189 					    MSG_ORIG(MSG_ARG_CYU));
1190 				else
1191 					Ulibdir = optarg + 2;
1192 			} else if (strncmp(optarg,
1193 			    MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1194 				if (Plibpath)
1195 					eprintf(ofl->ofl_lml, ERR_WARNING,
1196 					    MSG_INTL(MSG_ARG_MTONCE),
1197 					    MSG_ORIG(MSG_ARG_CYP));
1198 				else
1199 					Plibpath = optarg + 2;
1200 			} else {
1201 				eprintf(ofl->ofl_lml, ERR_FATAL,
1202 				    MSG_INTL(MSG_ARG_ILLEGAL),
1203 				    MSG_ORIG(MSG_ARG_CY), optarg);
1204 				ofl->ofl_flags |= FLG_OF_FATAL;
1205 			}
1206 			break;
1207 
1208 		case '?':
1209 			(*error)++;
1210 			break;
1211 
1212 		default:
1213 			break;
1214 		}
1215 	}
1216 	return (1);
1217 }
1218 
1219 /*
1220  * Parsing options pass2 for
1221  */
1222 static uintptr_t
1223 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1224 {
1225 	int	c;
1226 
1227 	while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
1228 		Ifl_desc	*ifl;
1229 		Sym_desc	*sdp;
1230 
1231 		DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c));
1232 		switch (c) {
1233 			case 'l':
1234 				if (ld_find_library(optarg, ofl) == S_ERROR)
1235 					return (S_ERROR);
1236 				break;
1237 			case 'B':
1238 				if (strcmp(optarg,
1239 				    MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1240 					if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1241 						ofl->ofl_flags |=
1242 							FLG_OF_DYNLIBS;
1243 					else {
1244 						eprintf(ofl->ofl_lml, ERR_FATAL,
1245 						    MSG_INTL(MSG_ARG_INCOMP),
1246 						    MSG_ORIG(MSG_ARG_DN),
1247 						    MSG_ORIG(MSG_ARG_BDYNAMIC));
1248 						ofl->ofl_flags |= FLG_OF_FATAL;
1249 					}
1250 				} else if (strcmp(optarg,
1251 				    MSG_ORIG(MSG_ARG_STATIC)) == 0)
1252 					ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1253 				break;
1254 			case 'L':
1255 				if (ld_add_libdir(ofl, optarg) == S_ERROR)
1256 					return (S_ERROR);
1257 				break;
1258 			case 'N':
1259 				/*
1260 				 * Record DT_NEEDED string
1261 				 */
1262 				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC)) {
1263 					eprintf(ofl->ofl_lml, ERR_FATAL,
1264 					    MSG_INTL(MSG_ARG_INCOMP),
1265 					    MSG_ORIG(MSG_ARG_DN),
1266 					    MSG_ORIG(MSG_ARG_CN));
1267 					ofl->ofl_flags |= FLG_OF_FATAL;
1268 				}
1269 				if (((ifl =
1270 				    libld_calloc(1, sizeof (Ifl_desc))) == 0) ||
1271 				    (list_appendc(&ofl->ofl_sos, ifl) == 0))
1272 					return (S_ERROR);
1273 
1274 				ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1275 				ifl->ifl_soname = optarg;
1276 				ifl->ifl_flags = (FLG_IF_NEEDSTR |
1277 				    FLG_IF_FILEREF | FLG_IF_DEPREQD);
1278 
1279 				break;
1280 			case 'D':
1281 				(void) dbg_setup(optarg, dbg_desc,
1282 				    &ofl->ofl_name, 2);
1283 				break;
1284 			case 'u':
1285 				if (ld_sym_add_u(optarg, ofl) ==
1286 				    (Sym_desc *)S_ERROR)
1287 					return (S_ERROR);
1288 				break;
1289 			case 'z':
1290 				if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1291 				    MSG_ARG_LD32_SIZE) == 0) ||
1292 				    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1293 				    MSG_ARG_LD64_SIZE) == 0)) {
1294 					if (createargv(ofl, 0) == S_ERROR)
1295 						return (S_ERROR);
1296 				} else if (strcmp(optarg,
1297 				    MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1298 					ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1299 					ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1300 				} else if (strcmp(optarg,
1301 				    MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1302 					ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1303 					ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1304 				} else if (strcmp(optarg,
1305 				    MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1306 					ofl->ofl_flags1 &=
1307 					~(FLG_OF1_ALLEXRT | FLG_OF1_WEAKEXT);
1308 				} else if (strcmp(optarg,
1309 				    MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1310 					ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1311 				} else if (strcmp(optarg,
1312 				    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1313 					ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1314 					ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
1315 				} else if (strcmp(optarg,
1316 				    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1317 					ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1318 				} else if (strcmp(optarg,
1319 				    MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1320 					ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1321 				} else if (strcmp(optarg,
1322 				    MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1323 					ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1324 				} else if (strcmp(optarg,
1325 				    MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1326 					ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1327 				} else if (strcmp(optarg,
1328 				    MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1329 					ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1330 				} else if (strcmp(optarg,
1331 				    MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1332 					ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1333 				} else if (strncmp(optarg,
1334 				    MSG_ORIG(MSG_ARG_INITARRAY),
1335 				    MSG_ARG_INITARRAY_SIZE) == 0) {
1336 					if (((sdp = ld_sym_add_u(optarg +
1337 					    MSG_ARG_INITARRAY_SIZE, ofl)) ==
1338 					    (Sym_desc *)S_ERROR) ||
1339 					    (list_appendc(&ofl->ofl_initarray,
1340 					    sdp) == 0))
1341 						return (S_ERROR);
1342 				} else if (strncmp(optarg,
1343 				    MSG_ORIG(MSG_ARG_FINIARRAY),
1344 				    MSG_ARG_FINIARRAY_SIZE) == 0) {
1345 					if (((sdp = ld_sym_add_u(optarg +
1346 					    MSG_ARG_FINIARRAY_SIZE, ofl)) ==
1347 					    (Sym_desc *)S_ERROR) ||
1348 					    (list_appendc(&ofl->ofl_finiarray,
1349 					    sdp) == 0))
1350 						return (S_ERROR);
1351 				} else if (strncmp(optarg,
1352 				    MSG_ORIG(MSG_ARG_PREINITARRAY),
1353 				    MSG_ARG_PREINITARRAY_SIZE) == 0) {
1354 					if (((sdp = ld_sym_add_u(optarg +
1355 					    MSG_ARG_PREINITARRAY_SIZE, ofl)) ==
1356 					    (Sym_desc *)S_ERROR) ||
1357 					    (list_appendc(&ofl->ofl_preiarray,
1358 					    sdp) == 0))
1359 						return (S_ERROR);
1360 				} else if (strncmp(optarg,
1361 				    MSG_ORIG(MSG_ARG_RTLDINFO),
1362 				    MSG_ARG_RTLDINFO_SIZE) == 0) {
1363 					if (((sdp = ld_sym_add_u(optarg +
1364 					    MSG_ARG_RTLDINFO_SIZE, ofl)) ==
1365 					    (Sym_desc *)S_ERROR) ||
1366 					    (list_appendc(&ofl->ofl_rtldinfo,
1367 					    sdp) == 0))
1368 						return (S_ERROR);
1369 				} else if (strncmp(optarg,
1370 				    MSG_ORIG(MSG_ARG_DTRACE),
1371 				    MSG_ARG_DTRACE_SIZE) == 0) {
1372 					if ((sdp = ld_sym_add_u(optarg +
1373 					    MSG_ARG_DTRACE_SIZE, ofl)) ==
1374 					    (Sym_desc *)S_ERROR)
1375 						return (S_ERROR);
1376 					ofl->ofl_dtracesym = sdp;
1377 				}
1378 			default:
1379 				break;
1380 		}
1381 	}
1382 	return (1);
1383 }
1384 
1385 /*
1386  *
1387  * Pass 1 -- process_flags: collects all options and sets flags
1388  */
1389 static uintptr_t
1390 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *e)
1391 {
1392 	for (; optind < argc; optind++) {
1393 		/*
1394 		 * If we detect some more options return to getopt().
1395 		 * Checking argv[optind][1] against null prevents a forever
1396 		 * loop if an unadorned `-' argument is passed to us.
1397 		 */
1398 		while ((optind < argc) && (argv[optind][0] == '-')) {
1399 			if (argv[optind][1] != '\0') {
1400 				if (parseopt_pass1(ofl, argc, argv, e) ==
1401 				    S_ERROR)
1402 					return (S_ERROR);
1403 			} else if (++optind < argc)
1404 				continue;
1405 		}
1406 		if (optind >= argc)
1407 			break;
1408 		ofl->ofl_objscnt++;
1409 	}
1410 	return (1);
1411 }
1412 
1413 uintptr_t
1414 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
1415 {
1416 	int	error = 0;	/* Collect all argument errors before exit */
1417 
1418 	if (argc < 2) {
1419 		usage_mesg(FALSE);
1420 		return (S_ERROR);
1421 	}
1422 
1423 	/*
1424 	 * Option handling
1425 	 */
1426 	if (process_flags_com(ofl, argc, argv, &error) == S_ERROR)
1427 		return (S_ERROR);
1428 
1429 	/*
1430 	 * Having parsed everything, did we have any errors.
1431 	 */
1432 	if (error) {
1433 		usage_mesg(TRUE);
1434 		return (S_ERROR);
1435 	}
1436 
1437 	return (check_flags(ofl, argc));
1438 }
1439 
1440 /*
1441  * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
1442  * files.
1443  */
1444 static uintptr_t
1445 process_files_com(Ofl_desc *ofl, int argc, char **argv)
1446 {
1447 	for (; optind < argc; optind++) {
1448 		int		fd;
1449 		Ifl_desc	*ifl;
1450 		Rej_desc	rej = { 0 };
1451 
1452 		/*
1453 		 * If we detect some more options return to getopt().
1454 		 * Checking argv[optind][1] against null prevents a forever
1455 		 * loop if an unadorned `-' argument is passed to us.
1456 		 */
1457 		while ((optind < argc) && (argv[optind][0] == '-')) {
1458 			if (argv[optind][1] != '\0') {
1459 				if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
1460 					return (S_ERROR);
1461 			} else if (++optind < argc)
1462 				continue;
1463 		}
1464 		if (optind >= argc)
1465 			break;
1466 
1467 		if ((fd = open(argv[optind], O_RDONLY)) == -1) {
1468 			int err = errno;
1469 
1470 			eprintf(ofl->ofl_lml, ERR_FATAL,
1471 			    MSG_INTL(MSG_SYS_OPEN), argv[optind],
1472 			    strerror(err));
1473 			ofl->ofl_flags |= FLG_OF_FATAL;
1474 			continue;
1475 		}
1476 
1477 		DBG_CALL(Dbg_args_files(ofl->ofl_lml, optind, argv[optind]));
1478 
1479 		ifl = ld_process_open(argv[optind], 0, fd, ofl,
1480 		    (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej);
1481 		(void) close(fd);
1482 		if (ifl == (Ifl_desc *)S_ERROR)
1483 			return (S_ERROR);
1484 
1485 		/*
1486 		 * Check for mismatched input.
1487 		 */
1488 		if (rej.rej_type) {
1489 			eprintf(ofl->ofl_lml, ERR_FATAL,
1490 			    MSG_INTL(reject[rej.rej_type]),
1491 			    rej.rej_name ? rej.rej_name :
1492 			    MSG_INTL(MSG_STR_UNKNOWN), conv_reject_desc(&rej));
1493 			ofl->ofl_flags |= FLG_OF_FATAL;
1494 			return (1);
1495 		}
1496 	}
1497 	return (1);
1498 }
1499 
1500 uintptr_t
1501 ld_process_files(Ofl_desc *ofl, int argc, char **argv)
1502 {
1503 	optind = 1;		/* reinitialize optind */
1504 
1505 	/*
1506 	 * Process command line files (taking into account any applicable
1507 	 * preseeding flags).  Return if any fatal errors have occurred.
1508 	 */
1509 	if (process_files_com(ofl, argc, argv) == S_ERROR)
1510 		return (S_ERROR);
1511 	if (ofl->ofl_flags & FLG_OF_FATAL)
1512 		return (1);
1513 
1514 	/*
1515 	 * Now that all command line files have been processed see if there are
1516 	 * any additional `needed' shared object dependencies.
1517 	 */
1518 	if (ofl->ofl_soneed.head)
1519 		if (ld_finish_libs(ofl) == S_ERROR)
1520 			return (S_ERROR);
1521 
1522 	/*
1523 	 * If rescanning archives is enabled, do so now to determine whether
1524 	 * there might still be members extracted to satisfy references from any
1525 	 * explicit objects.  Continue until no new objects are extracted.  Note
1526 	 * that this pass is carried out *after* processing any implicit objects
1527 	 * (above) as they may already have resolved any undefined references
1528 	 * from any explicit dependencies.
1529 	 */
1530 	if (ofl->ofl_flags1 & FLG_OF1_RESCAN)
1531 		ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
1532 	while ((ofl->ofl_flags1 & (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) ==
1533 	    (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) {
1534 		Listnode	*lnp;
1535 		Ar_desc		*adp;
1536 
1537 		ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT;
1538 
1539 		DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml));
1540 
1541 		for (LIST_TRAVERSE(&ofl->ofl_ars, lnp, adp)) {
1542 			const char	*name = adp->ad_name;
1543 			uintptr_t	error;
1544 			int		fd;
1545 
1546 			/*
1547 			 * If this archive was processed with -z allextract,
1548 			 * then all members have already been extracted.
1549 			 */
1550 			if (adp->ad_elf == (Elf *)NULL)
1551 				continue;
1552 
1553 			/*
1554 			 * Reopen the file.
1555 			 */
1556 			if ((fd = open(name, O_RDONLY)) == -1) {
1557 				int err = errno;
1558 
1559 				eprintf(ofl->ofl_lml, ERR_FATAL,
1560 				    MSG_INTL(MSG_SYS_OPEN), name,
1561 				    strerror(err));
1562 				ofl->ofl_flags |= FLG_OF_FATAL;
1563 				return (S_ERROR);
1564 			}
1565 
1566 			/*
1567 			 * Reestablish any archive specific command line flags.
1568 			 */
1569 			ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE;
1570 			ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE);
1571 
1572 			error = ld_process_archive(adp->ad_name, fd, adp, ofl);
1573 			(void) close(fd);
1574 
1575 			if (error == S_ERROR)
1576 				return (S_ERROR);
1577 			if (ofl->ofl_flags & FLG_OF_FATAL)
1578 				return (1);
1579 		}
1580 	}
1581 
1582 	/*
1583 	 * If debugging, provide statistics on each archives extraction, or flag
1584 	 * any archive that has provided no members.  Note that this could be a
1585 	 * nice place to free up much of the archive infrastructure, as we've
1586 	 * extracted any members we need.  However, as we presently don't free
1587 	 * anything under ld(1) there's not much point in proceeding further.
1588 	 */
1589 	DBG_CALL(Dbg_statistics_ar(ofl));
1590 
1591 	/*
1592 	 * If any version definitions have been established, either via input
1593 	 * from a mapfile or from the input relocatable objects, make sure any
1594 	 * version dependencies are satisfied, and version symbols created.
1595 	 */
1596 	if (ofl->ofl_verdesc.head)
1597 		if (ld_vers_check_defs(ofl) == S_ERROR)
1598 			return (S_ERROR);
1599 
1600 	/*
1601 	 * If segment ordering was specified (using mapfile) verify things
1602 	 * are ok.
1603 	 */
1604 	if (ofl->ofl_flags & FLG_OF_SEGORDER)
1605 		ld_ent_check(ofl);
1606 
1607 	return (1);
1608 }
1609 
1610 uintptr_t
1611 ld_init_strings(Ofl_desc *ofl)
1612 {
1613 	uint_t	stflags;
1614 
1615 	if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
1616 		stflags = 0;
1617 	else
1618 		stflags = FLG_STNEW_COMPRESS;
1619 
1620 	if (((ofl->ofl_shdrsttab = st_new(stflags)) == 0) ||
1621 	    ((ofl->ofl_strtab = st_new(stflags)) == 0) ||
1622 	    ((ofl->ofl_dynstrtab = st_new(stflags)) == 0))
1623 		return (S_ERROR);
1624 
1625 	return (0);
1626 }
1627