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