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