args.c revision 1682:79d68fa5aedd
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_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 */
190static uintptr_t
191check_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	 * Process any mapfiles after establishing the entrance criteria as
511	 * the user may be redefining or adding sections/segments.
512	 */
513	if (ofl->ofl_maps.head) {
514		Listnode	*lnp;
515		const char	*name;
516
517		for (LIST_TRAVERSE(&ofl->ofl_maps, lnp, name))
518			if (ld_map_parse(name, ofl) == S_ERROR)
519				return (S_ERROR);
520
521		if (ofl->ofl_flags & FLG_OF_SEGSORT)
522			if (ld_sort_seg_list(ofl) == S_ERROR)
523				return (S_ERROR);
524	}
525
526	/*
527	 * If -zloadfltr is set, verify that filtering is in effect.  Filters
528	 * are either established from the command line, and affect the whole
529	 * object, or are set on a per-symbol basis from a mapfile.
530	 */
531	if (zlflag) {
532		if ((ofl->ofl_filtees == 0) && (ofl->ofl_dtsfltrs == 0)) {
533			eprintf(ofl->ofl_lml, ERR_FATAL,
534			    MSG_INTL(MSG_ARG_NOFLTR),
535			    MSG_ORIG(MSG_ARG_ZLOADFLTR));
536			ofl->ofl_flags |= FLG_OF_FATAL;
537		}
538		ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
539	}
540
541	/*
542	 * Check that we have something to work with.  This check is carried out
543	 * after mapfile processing as its possible a mapfile is being used to
544	 * define symbols, in which case it would be sufficient to build the
545	 * output file purely from the mapfile.
546	 */
547	if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
548		if (Vflag && (argc == 2))
549			ofl->ofl_flags1 |= FLG_OF1_DONE;
550		else {
551			eprintf(ofl->ofl_lml, ERR_FATAL,
552			    MSG_INTL(MSG_ARG_NOFILES));
553			return (S_ERROR);
554		}
555	}
556	return (1);
557}
558
559/*
560 * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
561 * used as an argument to getopt().
562 *
563 * If the second argument 'error' is not 0, then this is called from the first
564 * pass. Else this is called from the second pass.
565 */
566static uintptr_t
567createargv(Ofl_desc *ofl, int *error)
568{
569	int		argc = 0, idx = 0, ooptind;
570	uintptr_t	ret;
571	char		**argv, *p0;
572
573	/*
574	 * The argument being examined is either:
575	 *	ld32= 	or
576	 *	ld64=
577	 */
578#if	defined(_LP64)
579	if (optarg[2] == '3')
580		return (0);
581#else
582	if (optarg[2] == '6')
583		return (0);
584#endif
585
586	p0 = &optarg[5];
587
588	/*
589	 * Count the number of arguments.
590	 */
591	while (*p0) {
592		/*
593		 * Pointing at non-separator character.
594		 */
595		if (*p0 != ',') {
596			argc++;
597			while (*p0 && (*p0 != ','))
598				p0++;
599			continue;
600		}
601
602		/*
603		 * Pointing at a separator character.
604		 */
605		if (*p0 == ',') {
606			while (*p0 == ',')
607				p0++;
608			continue;
609		}
610	}
611
612	if (argc == 0)
613		return (0);
614
615	/*
616	 * Allocate argument vector.
617	 */
618	if ((p0 = (char *)strdup(&optarg[5])) == 0)
619		return (S_ERROR);
620	if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == 0)
621		return (S_ERROR);
622
623	while (*p0) {
624		char *p;
625
626		/*
627		 * Pointing at the beginning of non-separator character string.
628		 */
629		if (*p0 != ',') {
630			p = p0;
631			while (*p0 && (*p0 != ','))
632				p0++;
633			argv[idx++] = p;
634			if (*p0) {
635				*p0 = '\0';
636				p0++;
637			}
638			continue;
639		}
640
641		/*
642		 * Pointing at the beginining of separator character string.
643		 */
644		if (*p0 == ',') {
645			while (*p0 == ',')
646				p0++;
647			continue;
648		}
649	}
650	argv[idx] = 0;
651	ooptind = optind;
652	optind = 0;
653
654	/*
655	 * Dispatch to pass1 or pass2
656	 */
657	if (error)
658		ret = process_flags_com(ofl, argc, argv, error);
659	else
660		ret = process_files_com(ofl, argc, argv);
661
662	optind = ooptind;
663
664	if (ret == S_ERROR)
665		return (S_ERROR);
666
667	return (argc);
668}
669
670/*
671 * Parsing options pass1 for process_flags().
672 */
673static uintptr_t
674parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *error)
675{
676	int	c;
677
678	while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
679		DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c));
680
681		switch (c) {
682		case '6':			/* Processed by ld to */
683			/*
684			 * -64 is processed by ld to determine the output class.
685			 * Here we sanity check the option incase some other
686			 * -6* option is mistakenly passed to us.
687			 */
688			if (optarg[0] != '4') {
689				eprintf(ofl->ofl_lml, ERR_FATAL,
690				    MSG_INTL(MSG_ARG_ILLEGAL),
691				    MSG_ORIG(MSG_ARG_6), optarg);
692				ofl->ofl_flags |= FLG_OF_FATAL;
693			}
694			continue;
695
696		case 'a':
697			aflag = TRUE;
698			break;
699
700		case 'b':
701			bflag = TRUE;
702			break;
703
704		case 'c':
705			if (ofl->ofl_config)
706				eprintf(ofl->ofl_lml, ERR_WARNING,
707				    MSG_INTL(MSG_ARG_MTONCE),
708				    MSG_ORIG(MSG_ARG_C));
709			else
710				ofl->ofl_config = optarg;
711			break;
712
713		case 'C':
714			demangle_flag = 1;
715			break;
716
717		case 'd':
718			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
719				if (dflag != SET_UNKNOWN)
720					eprintf(ofl->ofl_lml, ERR_WARNING,
721					    MSG_INTL(MSG_ARG_MTONCE),
722					    MSG_ORIG(MSG_ARG_D));
723				else
724					dflag = SET_FALSE;
725			} else if ((optarg[0] == 'y') && (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_TRUE;
732			} else {
733				eprintf(ofl->ofl_lml, ERR_FATAL,
734				    MSG_INTL(MSG_ARG_ILLEGAL),
735				    MSG_ORIG(MSG_ARG_D), optarg);
736				ofl->ofl_flags |= FLG_OF_FATAL;
737			}
738			break;
739
740		case 'e':
741			if (ofl->ofl_entry)
742				eprintf(ofl->ofl_lml, ERR_WARNING,
743				    MSG_INTL(MSG_ARG_MTONCE),
744				    MSG_ORIG(MSG_ARG_E));
745			else
746				ofl->ofl_entry = (void *)optarg;
747			break;
748
749		case 'f':
750			if (ofl->ofl_filtees &&
751			    (!(ofl->ofl_flags & FLG_OF_AUX))) {
752				eprintf(ofl->ofl_lml, ERR_FATAL,
753				    MSG_INTL(MSG_ARG_INCOMP),
754				    MSG_ORIG(MSG_ARG_F), MSG_ORIG(MSG_ARG_CF));
755				ofl->ofl_flags |= FLG_OF_FATAL;
756			} else {
757				if ((ofl->ofl_filtees =
758				    add_string(ofl->ofl_filtees, optarg)) ==
759				    (const char *)S_ERROR)
760					return (S_ERROR);
761				ofl->ofl_flags |= FLG_OF_AUX;
762			}
763			break;
764
765		case 'F':
766			if (ofl->ofl_filtees &&
767			    (ofl->ofl_flags & FLG_OF_AUX)) {
768				eprintf(ofl->ofl_lml, ERR_FATAL,
769				    MSG_INTL(MSG_ARG_INCOMP),
770				    MSG_ORIG(MSG_ARG_CF), MSG_ORIG(MSG_ARG_F));
771				ofl->ofl_flags |= FLG_OF_FATAL;
772			} else {
773				if ((ofl->ofl_filtees =
774				    add_string(ofl->ofl_filtees, optarg)) ==
775				    (const char *)S_ERROR)
776					return (S_ERROR);
777			}
778			break;
779
780		case 'h':
781			if (ofl->ofl_soname)
782				eprintf(ofl->ofl_lml, ERR_WARNING,
783				    MSG_INTL(MSG_ARG_MTONCE),
784				    MSG_ORIG(MSG_ARG_H));
785			else
786				ofl->ofl_soname = (const char *)optarg;
787			break;
788
789		case 'i':
790			ofl->ofl_flags |= FLG_OF_IGNENV;
791			break;
792
793		case 'I':
794			if (ofl->ofl_interp)
795				eprintf(ofl->ofl_lml, ERR_WARNING,
796				    MSG_INTL(MSG_ARG_MTONCE),
797				    MSG_ORIG(MSG_ARG_CI));
798			else
799				ofl->ofl_interp = (const char *)optarg;
800			break;
801
802		case 'l':
803			/*
804			 * For now, count any library as a shared object.  This
805			 * is used to size the internal symbol cache.  This
806			 * value is recalculated later on actual file processing
807			 * to get an accurate shared object count.
808			 */
809			ofl->ofl_soscnt++;
810			break;
811
812		case 'm':
813			ofl->ofl_flags |= FLG_OF_GENMAP;
814			break;
815
816		case 'o':
817			if (ofl->ofl_name)
818				eprintf(ofl->ofl_lml, ERR_WARNING,
819				    MSG_INTL(MSG_ARG_MTONCE),
820				    MSG_ORIG(MSG_ARG_O));
821			else
822				ofl->ofl_name = (const char *)optarg;
823			break;
824
825		case 'p':
826			/*
827			 * Multiple instances of this option may occur.  Each
828			 * additional instance is effectively concatenated to
829			 * the previous separated by a colon.
830			 */
831			if (*optarg != '\0') {
832				if ((ofl->ofl_audit =
833				    add_string(ofl->ofl_audit,
834				    optarg)) == (const char *)S_ERROR)
835					return (S_ERROR);
836			}
837			break;
838
839		case 'P':
840			/*
841			 * Multiple instances of this option may occur.  Each
842			 * additional instance is effectively concatenated to
843			 * the previous separated by a colon.
844			 */
845			if (*optarg != '\0') {
846				if ((ofl->ofl_depaudit =
847				    add_string(ofl->ofl_depaudit,
848				    optarg)) == (const char *)S_ERROR)
849					return (S_ERROR);
850			}
851			break;
852
853		case 'r':
854			rflag = TRUE;
855			break;
856
857		case 'R':
858			/*
859			 * Multiple instances of this option may occur.  Each
860			 * additional instance is effectively concatenated to
861			 * the previous separated by a colon.
862			 */
863			if (*optarg != '\0') {
864				if ((ofl->ofl_rpath =
865				    add_string(ofl->ofl_rpath,
866				    optarg)) == (const char *)S_ERROR)
867					return (S_ERROR);
868			}
869			break;
870
871		case 's':
872			sflag = TRUE;
873			break;
874
875		case 't':
876			ofl->ofl_flags |= FLG_OF_NOWARN;
877			break;
878
879		case 'u':
880			break;
881
882		case 'z':
883			/*
884			 * For specific help, print our usage message and exit
885			 * immediately to insure a 0 return code.
886			 */
887			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
888			    MSG_ARG_HELP_SIZE) == 0) {
889				usage_mesg(1);
890				exit(0);
891			}
892
893			/*
894			 * For some options set a flag - further consistancy
895			 * checks will be carried out in check_flags().
896			 */
897			if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
898			    MSG_ARG_LD32_SIZE) == 0) ||
899			    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
900			    MSG_ARG_LD64_SIZE) == 0)) {
901				if (createargv(ofl, error) == S_ERROR)
902					return (S_ERROR);
903
904			} else if (
905			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
906				if (zdflag != SET_UNKNOWN)
907					eprintf(ofl->ofl_lml, ERR_WARNING,
908					    MSG_INTL(MSG_ARG_MTONCE),
909					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
910				else
911					zdflag = SET_TRUE;
912			} else if (strcmp(optarg,
913			    MSG_ORIG(MSG_ARG_NODEFS)) == 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_FALSE;
920			} else if (strcmp(optarg,
921			    MSG_ORIG(MSG_ARG_TEXT)) == 0) {
922				if (ztflag &&
923				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT))) {
924					eprintf(ofl->ofl_lml, ERR_FATAL,
925					    MSG_INTL(MSG_ARG_INCOMP),
926					    MSG_ORIG(MSG_ARG_ZTEXT),
927					    ztflag);
928					ofl->ofl_flags |= FLG_OF_FATAL;
929				}
930				ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
931			} else if (strcmp(optarg,
932			    MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
933				if (ztflag &&
934				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF))) {
935					eprintf(ofl->ofl_lml, ERR_FATAL,
936					    MSG_INTL(MSG_ARG_INCOMP),
937					    MSG_ORIG(MSG_ARG_ZTEXTOFF),
938					    ztflag);
939					ofl->ofl_flags |= FLG_OF_FATAL;
940				}
941				ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
942			} else if (strcmp(optarg,
943			    MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
944				if (ztflag &&
945				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN))) {
946					eprintf(ofl->ofl_lml, ERR_FATAL,
947					    MSG_INTL(MSG_ARG_INCOMP),
948					    MSG_ORIG(MSG_ARG_ZTEXTWARN),
949					    ztflag);
950					ofl->ofl_flags |= FLG_OF_FATAL;
951				}
952				ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
953
954			/*
955			 * For other options simply set the ofl flags directly.
956			 */
957			} else if (strcmp(optarg,
958			    MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
959				ofl->ofl_flags1 |= FLG_OF1_RESCAN;
960			} else if (strcmp(optarg,
961			    MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
962				ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
963			} else if (strcmp(optarg,
964			    MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
965				zlflag = TRUE;
966			} else if (strcmp(optarg,
967			    MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
968				ofl->ofl_dtflags_1 |= DF_1_NORELOC;
969			} else if (strcmp(optarg,
970			    MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
971				ofl->ofl_flags |= FLG_OF_NOVERSEC;
972			} else if (strcmp(optarg,
973			    MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
974				ofl->ofl_flags |= FLG_OF_MULDEFS;
975			} else if (strcmp(optarg,
976			    MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
977				ofl->ofl_flags1 |= FLG_OF1_REDLSYM;
978			} else if (strcmp(optarg,
979			    MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
980				ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
981			} else if (strcmp(optarg,
982			    MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
983				ofl->ofl_dtflags_1 |= DF_1_NODELETE;
984			} else if (strcmp(optarg,
985			    MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
986				ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
987			} else if (strcmp(optarg,
988			    MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
989				ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
990			} else if (strcmp(optarg,
991			    MSG_ORIG(MSG_ARG_NOW)) == 0) {
992				ofl->ofl_dtflags_1 |= DF_1_NOW;
993				ofl->ofl_dtflags |= DF_BIND_NOW;
994			} else if (strcmp(optarg,
995			    MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
996				ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
997				ofl->ofl_dtflags |= DF_ORIGIN;
998			} else if (strcmp(optarg,
999			    MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1000				ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1001			} else if (strcmp(optarg,
1002			    MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1003				ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1004			} else if (strcmp(optarg,
1005			    MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1006				ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1007			} else if (strcmp(optarg,
1008			    MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1009				ofl->ofl_flags |= FLG_OF_VERBOSE;
1010			} else if (strcmp(optarg,
1011			    MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1012				ofl->ofl_flags1 |= FLG_OF1_RELCNT;
1013			} else if (strcmp(optarg,
1014			    MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1015				ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1016			} else if (strcmp(optarg,
1017			    MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1018				zinflag = TRUE;
1019			} else if (strcmp(optarg,
1020			    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1021				ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1022
1023			/*
1024			 * The following options just need validation as they
1025			 * are interpreted on the second pass through the
1026			 * command line arguments.
1027			 */
1028			} else if (
1029			    strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1030				MSG_ARG_INITARRAY_SIZE) &&
1031			    strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1032				MSG_ARG_FINIARRAY_SIZE) &&
1033			    strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1034				MSG_ARG_PREINITARRAY_SIZE) &&
1035			    strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1036				MSG_ARG_RTLDINFO_SIZE) &&
1037			    strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1038				MSG_ARG_DTRACE_SIZE) &&
1039			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1040			    strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1041			    strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1042			    strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1043			    strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1044			    strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1045			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1046			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1047			    strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1048			    strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT))) {
1049				eprintf(ofl->ofl_lml, ERR_FATAL,
1050				    MSG_INTL(MSG_ARG_ILLEGAL),
1051				    MSG_ORIG(MSG_ARG_Z), optarg);
1052				ofl->ofl_flags |= FLG_OF_FATAL;
1053
1054			}
1055
1056			break;
1057
1058		case 'D':
1059			/*
1060			 * If we have not yet read any input files go ahead
1061			 * and process any debugging options (this allows any
1062			 * argument processing, entrance criteria and library
1063			 * initialization to be displayed).  Otherwise, if an
1064			 * input file has been seen, skip interpretation until
1065			 * process_files (this allows debugging to be turned
1066			 * on and off around individual groups of files).
1067			 */
1068			if (ofl->ofl_objscnt == 0) {
1069				if (dbg_setup(optarg, dbg_desc,
1070				    &ofl->ofl_name, 1) == S_ERROR)
1071					return (S_ERROR);
1072			}
1073			break;
1074
1075		case 'B':
1076			if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1077				if (Bdflag == SET_FALSE) {
1078					eprintf(ofl->ofl_lml, ERR_FATAL,
1079					    MSG_INTL(MSG_ARG_INCOMP),
1080					    MSG_ORIG(MSG_ARG_BNODIRECT),
1081					    MSG_ORIG(MSG_ARG_BDIRECT));
1082					ofl->ofl_flags |= FLG_OF_FATAL;
1083				} else
1084					Bdflag = SET_TRUE;
1085			} else if (strcmp(optarg,
1086			    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1087				if (Bdflag == SET_TRUE) {
1088					eprintf(ofl->ofl_lml, ERR_FATAL,
1089					    MSG_INTL(MSG_ARG_INCOMP),
1090					    MSG_ORIG(MSG_ARG_BDIRECT),
1091					    MSG_ORIG(MSG_ARG_BNODIRECT));
1092					ofl->ofl_flags |= FLG_OF_FATAL;
1093				} else
1094					Bdflag = SET_FALSE;
1095			} else if (strcmp(optarg,
1096			    MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1097				Bsflag = TRUE;
1098			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1099				ofl->ofl_flags |= FLG_OF_PROCRED;
1100			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1101				Blflag = TRUE;
1102			else if (strcmp(optarg,
1103			    MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0)
1104				Btflag = TRUE;
1105			else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1106				Bgflag = TRUE;
1107			else if (strcmp(optarg,
1108			    MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1109				Beflag = TRUE;
1110			else if (strcmp(optarg, MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1111			    strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1112				eprintf(ofl->ofl_lml, ERR_FATAL,
1113				    MSG_INTL(MSG_ARG_ILLEGAL),
1114				    MSG_ORIG(MSG_ARG_CB), optarg);
1115				ofl->ofl_flags |= FLG_OF_FATAL;
1116			}
1117			break;
1118
1119		case 'G':
1120			Gflag = TRUE;
1121			break;
1122
1123		case 'L':
1124			break;
1125
1126		case 'M':
1127			if (list_appendc(&(ofl->ofl_maps), optarg) == 0)
1128				return (S_ERROR);
1129			break;
1130
1131		case 'N':
1132			break;
1133
1134		case 'Q':
1135			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1136				if (Qflag != SET_UNKNOWN)
1137					eprintf(ofl->ofl_lml, ERR_WARNING,
1138					    MSG_INTL(MSG_ARG_MTONCE),
1139					    MSG_ORIG(MSG_ARG_CQ));
1140				else
1141					Qflag = SET_FALSE;
1142			} else if ((optarg[0] == 'y') && (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_TRUE;
1149			} else {
1150				eprintf(ofl->ofl_lml, ERR_FATAL,
1151				    MSG_INTL(MSG_ARG_ILLEGAL),
1152				    MSG_ORIG(MSG_ARG_CQ), optarg);
1153				ofl->ofl_flags |= FLG_OF_FATAL;
1154			}
1155			break;
1156
1157		case 'S':
1158			if (list_appendc(&lib_support, optarg) == 0)
1159				return (S_ERROR);
1160			break;
1161
1162		case 'V':
1163			if (!Vflag)
1164				(void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1165				    ofl->ofl_sgsid);
1166			Vflag = TRUE;
1167			break;
1168
1169		case 'Y':
1170			if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1171				if (Llibdir)
1172				    eprintf(ofl->ofl_lml, ERR_WARNING,
1173					MSG_INTL(MSG_ARG_MTONCE),
1174					MSG_ORIG(MSG_ARG_CYL));
1175				else
1176					Llibdir = optarg + 2;
1177			} else if (strncmp(optarg,
1178			    MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1179				if (Ulibdir)
1180					eprintf(ofl->ofl_lml, ERR_WARNING,
1181					    MSG_INTL(MSG_ARG_MTONCE),
1182					    MSG_ORIG(MSG_ARG_CYU));
1183				else
1184					Ulibdir = optarg + 2;
1185			} else if (strncmp(optarg,
1186			    MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1187				if (Plibpath)
1188					eprintf(ofl->ofl_lml, ERR_WARNING,
1189					    MSG_INTL(MSG_ARG_MTONCE),
1190					    MSG_ORIG(MSG_ARG_CYP));
1191				else
1192					Plibpath = optarg + 2;
1193			} else {
1194				eprintf(ofl->ofl_lml, ERR_FATAL,
1195				    MSG_INTL(MSG_ARG_ILLEGAL),
1196				    MSG_ORIG(MSG_ARG_CY), optarg);
1197				ofl->ofl_flags |= FLG_OF_FATAL;
1198			}
1199			break;
1200
1201		case '?':
1202			(*error)++;
1203			break;
1204
1205		default:
1206			break;
1207		}
1208	}
1209	return (1);
1210}
1211
1212/*
1213 * Parsing options pass2 for
1214 */
1215static uintptr_t
1216parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1217{
1218	int	c;
1219
1220	while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
1221		Ifl_desc	*ifl;
1222		Sym_desc	*sdp;
1223
1224		DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c));
1225		switch (c) {
1226			case 'l':
1227				if (ld_find_library(optarg, ofl) == S_ERROR)
1228					return (S_ERROR);
1229				break;
1230			case 'B':
1231				if (strcmp(optarg,
1232				    MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1233					if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1234						ofl->ofl_flags |=
1235							FLG_OF_DYNLIBS;
1236					else {
1237						eprintf(ofl->ofl_lml, ERR_FATAL,
1238						    MSG_INTL(MSG_ARG_INCOMP),
1239						    MSG_ORIG(MSG_ARG_DN),
1240						    MSG_ORIG(MSG_ARG_BDYNAMIC));
1241						ofl->ofl_flags |= FLG_OF_FATAL;
1242					}
1243				} else if (strcmp(optarg,
1244				    MSG_ORIG(MSG_ARG_STATIC)) == 0)
1245					ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1246				break;
1247			case 'L':
1248				if (ld_add_libdir(ofl, optarg) == S_ERROR)
1249					return (S_ERROR);
1250				break;
1251			case 'N':
1252				/*
1253				 * Record DT_NEEDED string
1254				 */
1255				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC)) {
1256					eprintf(ofl->ofl_lml, ERR_FATAL,
1257					    MSG_INTL(MSG_ARG_INCOMP),
1258					    MSG_ORIG(MSG_ARG_DN),
1259					    MSG_ORIG(MSG_ARG_CN));
1260					ofl->ofl_flags |= FLG_OF_FATAL;
1261				}
1262				if (((ifl =
1263				    libld_calloc(1, sizeof (Ifl_desc))) == 0) ||
1264				    (list_appendc(&ofl->ofl_sos, ifl) == 0))
1265					return (S_ERROR);
1266
1267				ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1268				ifl->ifl_soname = optarg;
1269				ifl->ifl_flags = (FLG_IF_NEEDSTR |
1270				    FLG_IF_FILEREF | FLG_IF_DEPREQD);
1271
1272				break;
1273			case 'D':
1274				(void) dbg_setup(optarg, dbg_desc,
1275				    &ofl->ofl_name, 2);
1276				break;
1277			case 'u':
1278				if (ld_sym_add_u(optarg, ofl) ==
1279				    (Sym_desc *)S_ERROR)
1280					return (S_ERROR);
1281				break;
1282			case 'z':
1283				if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1284				    MSG_ARG_LD32_SIZE) == 0) ||
1285				    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1286				    MSG_ARG_LD64_SIZE) == 0)) {
1287					if (createargv(ofl, 0) == S_ERROR)
1288						return (S_ERROR);
1289				} else if (strcmp(optarg,
1290				    MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1291					ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1292					ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1293				} else if (strcmp(optarg,
1294				    MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1295					ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1296					ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1297				} else if (strcmp(optarg,
1298				    MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1299					ofl->ofl_flags1 &=
1300					~(FLG_OF1_ALLEXRT | FLG_OF1_WEAKEXT);
1301				} else if (strcmp(optarg,
1302				    MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1303					ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1304				} else if (strcmp(optarg,
1305				    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1306					ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1307					ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
1308				} else if (strcmp(optarg,
1309				    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1310					ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1311				} else if (strcmp(optarg,
1312				    MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1313					ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1314				} else if (strcmp(optarg,
1315				    MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1316					ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1317				} else if (strcmp(optarg,
1318				    MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1319					ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1320				} else if (strcmp(optarg,
1321				    MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1322					ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1323				} else if (strcmp(optarg,
1324				    MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1325					ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1326				} else if (strncmp(optarg,
1327				    MSG_ORIG(MSG_ARG_INITARRAY),
1328				    MSG_ARG_INITARRAY_SIZE) == 0) {
1329					if (((sdp = ld_sym_add_u(optarg +
1330					    MSG_ARG_INITARRAY_SIZE, ofl)) ==
1331					    (Sym_desc *)S_ERROR) ||
1332					    (list_appendc(&ofl->ofl_initarray,
1333					    sdp) == 0))
1334						return (S_ERROR);
1335				} else if (strncmp(optarg,
1336				    MSG_ORIG(MSG_ARG_FINIARRAY),
1337				    MSG_ARG_FINIARRAY_SIZE) == 0) {
1338					if (((sdp = ld_sym_add_u(optarg +
1339					    MSG_ARG_FINIARRAY_SIZE, ofl)) ==
1340					    (Sym_desc *)S_ERROR) ||
1341					    (list_appendc(&ofl->ofl_finiarray,
1342					    sdp) == 0))
1343						return (S_ERROR);
1344				} else if (strncmp(optarg,
1345				    MSG_ORIG(MSG_ARG_PREINITARRAY),
1346				    MSG_ARG_PREINITARRAY_SIZE) == 0) {
1347					if (((sdp = ld_sym_add_u(optarg +
1348					    MSG_ARG_PREINITARRAY_SIZE, ofl)) ==
1349					    (Sym_desc *)S_ERROR) ||
1350					    (list_appendc(&ofl->ofl_preiarray,
1351					    sdp) == 0))
1352						return (S_ERROR);
1353				} else if (strncmp(optarg,
1354				    MSG_ORIG(MSG_ARG_RTLDINFO),
1355				    MSG_ARG_RTLDINFO_SIZE) == 0) {
1356					if (((sdp = ld_sym_add_u(optarg +
1357					    MSG_ARG_RTLDINFO_SIZE, ofl)) ==
1358					    (Sym_desc *)S_ERROR) ||
1359					    (list_appendc(&ofl->ofl_rtldinfo,
1360					    sdp) == 0))
1361						return (S_ERROR);
1362				} else if (strncmp(optarg,
1363				    MSG_ORIG(MSG_ARG_DTRACE),
1364				    MSG_ARG_DTRACE_SIZE) == 0) {
1365					if ((sdp = ld_sym_add_u(optarg +
1366					    MSG_ARG_DTRACE_SIZE, ofl)) ==
1367					    (Sym_desc *)S_ERROR)
1368						return (S_ERROR);
1369					ofl->ofl_dtracesym = sdp;
1370				}
1371			default:
1372				break;
1373		}
1374	}
1375	return (1);
1376}
1377
1378/*
1379 *
1380 * Pass 1 -- process_flags: collects all options and sets flags
1381 */
1382static uintptr_t
1383process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *e)
1384{
1385	for (; optind < argc; optind++) {
1386		/*
1387		 * If we detect some more options return to getopt().
1388		 * Checking argv[optind][1] against null prevents a forever
1389		 * loop if an unadorned `-' argument is passed to us.
1390		 */
1391		while ((optind < argc) && (argv[optind][0] == '-')) {
1392			if (argv[optind][1] != '\0') {
1393				if (parseopt_pass1(ofl, argc, argv, e) ==
1394				    S_ERROR)
1395					return (S_ERROR);
1396			} else if (++optind < argc)
1397				continue;
1398		}
1399		if (optind >= argc)
1400			break;
1401		ofl->ofl_objscnt++;
1402	}
1403	return (1);
1404}
1405
1406uintptr_t
1407ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
1408{
1409	int	error = 0;	/* Collect all argument errors before exit */
1410
1411	if (argc < 2) {
1412		usage_mesg(FALSE);
1413		return (S_ERROR);
1414	}
1415
1416	/*
1417	 * Option handling
1418	 */
1419	if (process_flags_com(ofl, argc, argv, &error) == S_ERROR)
1420		return (S_ERROR);
1421
1422	/*
1423	 * Having parsed everything, did we have any errors.
1424	 */
1425	if (error) {
1426		usage_mesg(TRUE);
1427		return (S_ERROR);
1428	}
1429
1430	return (check_flags(ofl, argc));
1431}
1432
1433/*
1434 * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
1435 * files.
1436 */
1437static uintptr_t
1438process_files_com(Ofl_desc *ofl, int argc, char **argv)
1439{
1440	for (; optind < argc; optind++) {
1441		int		fd;
1442		Ifl_desc	*ifl;
1443		Rej_desc	rej = { 0 };
1444
1445		/*
1446		 * If we detect some more options return to getopt().
1447		 * Checking argv[optind][1] against null prevents a forever
1448		 * loop if an unadorned `-' argument is passed to us.
1449		 */
1450		while ((optind < argc) && (argv[optind][0] == '-')) {
1451			if (argv[optind][1] != '\0') {
1452				if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
1453					return (S_ERROR);
1454			} else if (++optind < argc)
1455				continue;
1456		}
1457		if (optind >= argc)
1458			break;
1459
1460		if ((fd = open(argv[optind], O_RDONLY)) == -1) {
1461			int err = errno;
1462
1463			eprintf(ofl->ofl_lml, ERR_FATAL,
1464			    MSG_INTL(MSG_SYS_OPEN), argv[optind],
1465			    strerror(err));
1466			ofl->ofl_flags |= FLG_OF_FATAL;
1467			continue;
1468		}
1469
1470		DBG_CALL(Dbg_args_files(ofl->ofl_lml, optind, argv[optind]));
1471
1472		ifl = ld_process_open(argv[optind], 0, fd, ofl,
1473		    (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej);
1474		(void) close(fd);
1475		if (ifl == (Ifl_desc *)S_ERROR)
1476			return (S_ERROR);
1477
1478		/*
1479		 * Check for mismatched input.
1480		 */
1481		if (rej.rej_type) {
1482			eprintf(ofl->ofl_lml, ERR_FATAL,
1483			    MSG_INTL(reject[rej.rej_type]),
1484			    rej.rej_name ? rej.rej_name :
1485			    MSG_INTL(MSG_STR_UNKNOWN), conv_reject_desc(&rej));
1486			ofl->ofl_flags |= FLG_OF_FATAL;
1487			return (1);
1488		}
1489	}
1490	return (1);
1491}
1492
1493uintptr_t
1494ld_process_files(Ofl_desc *ofl, int argc, char **argv)
1495{
1496	optind = 1;		/* reinitialize optind */
1497
1498	/*
1499	 * Process command line files (taking into account any applicable
1500	 * preseeding flags).  Return if any fatal errors have occurred.
1501	 */
1502	if (process_files_com(ofl, argc, argv) == S_ERROR)
1503		return (S_ERROR);
1504	if (ofl->ofl_flags & FLG_OF_FATAL)
1505		return (1);
1506
1507	/*
1508	 * Now that all command line files have been processed see if there are
1509	 * any additional `needed' shared object dependencies.
1510	 */
1511	if (ofl->ofl_soneed.head)
1512		if (ld_finish_libs(ofl) == S_ERROR)
1513			return (S_ERROR);
1514
1515	/*
1516	 * If rescanning archives is enabled, do so now to determine whether
1517	 * there might still be members extracted to satisfy references from any
1518	 * explicit objects.  Continue until no new objects are extracted.  Note
1519	 * that this pass is carried out *after* processing any implicit objects
1520	 * (above) as they may already have resolved any undefined references
1521	 * from any explicit dependencies.
1522	 */
1523	if (ofl->ofl_flags1 & FLG_OF1_RESCAN)
1524		ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
1525	while ((ofl->ofl_flags1 & (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) ==
1526	    (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) {
1527		Listnode	*lnp;
1528		Ar_desc		*adp;
1529
1530		ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT;
1531
1532		DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml));
1533
1534		for (LIST_TRAVERSE(&ofl->ofl_ars, lnp, adp)) {
1535			const char	*name = adp->ad_name;
1536			uintptr_t	error;
1537			int		fd;
1538
1539			/*
1540			 * If this archive was processed with -z allextract,
1541			 * then all members have already been extracted.
1542			 */
1543			if (adp->ad_elf == (Elf *)NULL)
1544				continue;
1545
1546			/*
1547			 * Reopen the file.
1548			 */
1549			if ((fd = open(name, O_RDONLY)) == -1) {
1550				int err = errno;
1551
1552				eprintf(ofl->ofl_lml, ERR_FATAL,
1553				    MSG_INTL(MSG_SYS_OPEN), name,
1554				    strerror(err));
1555				ofl->ofl_flags |= FLG_OF_FATAL;
1556				return (S_ERROR);
1557			}
1558
1559			/*
1560			 * Reestablish any archive specific command line flags.
1561			 */
1562			ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE;
1563			ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE);
1564
1565			error = ld_process_archive(adp->ad_name, fd, adp, ofl);
1566			(void) close(fd);
1567
1568			if (error == S_ERROR)
1569				return (S_ERROR);
1570			if (ofl->ofl_flags & FLG_OF_FATAL)
1571				return (1);
1572		}
1573	}
1574
1575	/*
1576	 * If debugging, provide statistics on each archives extraction, or flag
1577	 * any archive that has provided no members.  Note that this could be a
1578	 * nice place to free up much of the archive infrastructure, as we've
1579	 * extracted any members we need.  However, as we presently don't free
1580	 * anything under ld(1) there's not much point in proceeding further.
1581	 */
1582	DBG_CALL(Dbg_statistics_ar(ofl));
1583
1584	/*
1585	 * If any version definitions have been established, either via input
1586	 * from a mapfile or from the input relocatable objects, make sure any
1587	 * version dependencies are satisfied, and version symbols created.
1588	 */
1589	if (ofl->ofl_verdesc.head)
1590		if (ld_vers_check_defs(ofl) == S_ERROR)
1591			return (S_ERROR);
1592
1593	/*
1594	 * If segment ordering was specified (using mapfile) verify things
1595	 * are ok.
1596	 */
1597	if (ofl->ofl_flags & FLG_OF_SEGORDER)
1598		ld_ent_check(ofl);
1599
1600	return (1);
1601}
1602