7029 want per-process exploit mitigation features (secflags)
[unleashed.git] / usr / src / cmd / sgs / libld / common / args.c
blob495fed322c3e474f82dc4d9ff6526fa6e6b8c86f
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
29 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
33 * Publicly available flags are defined in ld(1). The following flags are
34 * private, and may be removed at any time.
36 * OPTION MEANING
38 * -z dtrace=symbol assigns symbol to PT_SUNWDTRACE segment,
39 * providing scratch area for dtrace processing.
41 * -z noreloc suppress relocation processing. This provides
42 * a mechanism for validating kernel module symbol
43 * resolution that would normally incur fatal
44 * relocation errors.
46 * -z rtldinfo=symbol assigns symbol to SUNW_RTLDINF dynamic tag,
47 * providing pre-initialization specific routines
48 * for TLS initialization.
50 * -z nointerp suppress the addition of an interpreter
51 * section. This is used to generate the kernel,
52 * but makes no sense to be used by anyone else.
54 * -z norelaxreloc suppress the automatic addition of relaxed
55 * relocations to GNU linkonce/COMDAT sections.
57 * -z nosighandler suppress the registration of the signal handler
58 * used to manage SIGBUS.
62 * The following flags are committed, and will not be removed, but are
63 * not publically documented, either because they are obsolete, or because
64 * they exist to work around defects in other software and are not of
65 * sufficient interest otherwise.
67 * OPTION MEANING
69 * -Wl,... compiler drivers and configuration tools
70 * have been known to pass this compiler option
71 * to ld(1). Strip off the "-Wl," prefix and
72 * process the remainder (...) as a normal option.
75 #include <sys/link.h>
76 #include <stdio.h>
77 #include <fcntl.h>
78 #include <string.h>
79 #include <errno.h>
80 #include <elf.h>
81 #include <unistd.h>
82 #include <debug.h>
83 #include "msg.h"
84 #include "_libld.h"
87 * Define a set of local argument flags, the settings of these will be
88 * verified in check_flags() and lead to the appropriate output file flags
89 * being initialized.
91 typedef enum {
92 SET_UNKNOWN = -1,
93 SET_FALSE = 0,
94 SET_TRUE = 1
95 } Setstate;
97 static Setstate dflag = SET_UNKNOWN;
98 static Setstate zdflag = SET_UNKNOWN;
99 static Setstate Qflag = SET_UNKNOWN;
100 static Setstate Bdflag = SET_UNKNOWN;
101 static Setstate zfwflag = SET_UNKNOWN;
103 static Boolean aflag = FALSE;
104 static Boolean bflag = FALSE;
105 static Boolean rflag = FALSE;
106 static Boolean sflag = FALSE;
107 static Boolean zinflag = FALSE;
108 static Boolean zlflag = FALSE;
109 static Boolean Bgflag = FALSE;
110 static Boolean Blflag = FALSE;
111 static Boolean Beflag = FALSE;
112 static Boolean Bsflag = FALSE;
113 static Boolean Dflag = FALSE;
114 static Boolean Gflag = FALSE;
115 static Boolean Vflag = FALSE;
118 * ztflag's state is set by pointing it to the matching string:
119 * text | textoff | textwarn
121 static const char *ztflag = NULL;
124 * Remember the guidance flags that result from the initial -z guidance
125 * option, so that they can be compared to any that follow. We only want
126 * to issue a warning when they differ.
128 static ofl_guideflag_t initial_guidance_flags = 0;
130 static uintptr_t process_files_com(Ofl_desc *, int, char **);
131 static uintptr_t process_flags_com(Ofl_desc *, int, char **, int *);
134 * Print usage message to stderr - 2 modes, summary message only,
135 * and full usage message.
137 static void
138 usage_mesg(Boolean detail)
140 (void) fprintf(stderr, MSG_INTL(MSG_ARG_USAGE),
141 MSG_ORIG(MSG_STR_OPTIONS));
143 if (detail == FALSE)
144 return;
146 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_3));
147 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_6));
148 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_A));
149 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_B));
150 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDR));
151 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBDY));
152 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBE));
153 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBG));
154 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBL));
155 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBR));
156 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CBS));
157 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_C));
158 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CC));
159 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_D));
160 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CD));
161 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_E));
162 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_F));
163 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CF));
164 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CG));
165 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_H));
166 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_I));
167 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CI));
168 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_L));
169 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CL));
170 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_M));
171 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CM));
172 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CN));
173 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_O));
174 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_P));
175 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CP));
176 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CQ));
177 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_R));
178 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CR));
179 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_S));
180 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CS));
181 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_T));
182 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_U));
183 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CV));
184 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY));
185 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA));
186 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
187 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL));
188 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZADLIB));
189 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
190 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDEF));
191 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
192 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
193 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
194 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFATW));
195 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFA));
196 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGP));
197 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGUIDE));
198 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZH));
199 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZIG));
200 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINA));
201 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINI));
202 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINT));
203 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLAZY));
204 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD32));
205 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLD64));
206 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZLO));
207 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZM));
208 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNC));
209 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDFS));
210 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEF));
211 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDEL));
212 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDLO));
213 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNDU));
214 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNLD));
215 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNOW));
216 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNPA));
217 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNV));
218 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZO));
219 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZPIA));
220 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRL));
221 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRREL));
222 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRS));
223 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSN));
224 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZRSGRP));
225 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZSCAP));
226 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTARG));
227 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT));
228 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO));
229 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW));
230 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZWRAP));
231 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZVER));
235 * Rescan the archives seen on the command line in order
236 * to handle circularly dependent archives, stopping when
237 * no further member extraction occurs.
239 * entry:
240 * ofl - Output file descriptor
241 * isgrp - True if this is a an archive group search, False
242 * to search starting with argv[1] through end_arg_ndx
243 * end_arg_ndx - Index of final argv element to consider.
245 static uintptr_t
246 ld_rescan_archives(Ofl_desc *ofl, int isgrp, int end_arg_ndx)
248 ofl->ofl_flags1 |= FLG_OF1_EXTRACT;
250 while (ofl->ofl_flags1 & FLG_OF1_EXTRACT) {
251 Aliste idx;
252 Ar_desc *adp;
253 Word start_ndx = isgrp ? ofl->ofl_ars_gsndx : 0;
254 Word ndx = 0;
256 ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT;
258 DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml,
259 isgrp ? ofl->ofl_ars_gsandx : 1, end_arg_ndx));
261 for (APLIST_TRAVERSE(ofl->ofl_ars, idx, adp)) {
262 /* If not to starting index yet, skip it */
263 if (ndx++ < start_ndx)
264 continue;
267 * If this archive was processed with -z allextract,
268 * then all members have already been extracted.
270 if (adp->ad_elf == NULL)
271 continue;
274 * Reestablish any archive specific command line flags.
276 ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE;
277 ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE);
280 * Re-process the archive. Note that a file descriptor
281 * is unnecessary, as the file is already available in
282 * memory.
284 if (!ld_process_archive(adp->ad_name, -1, adp, ofl))
285 return (S_ERROR);
286 if (ofl->ofl_flags & FLG_OF_FATAL)
287 return (1);
291 return (1);
295 * Checks the command line option flags for consistency.
297 static uintptr_t
298 check_flags(Ofl_desc * ofl, int argc)
301 * If the user specified -zguidance=noall, then we can safely disable
302 * the entire feature. The purpose of -zguidance=noall is to allow
303 * the user to override guidance specified from a makefile via
304 * the LD_OPTIONS environment variable, and so, we want to behave
305 * in exactly the same manner we would have if no option were present.
307 if ((ofl->ofl_guideflags & (FLG_OFG_ENABLE | FLG_OFG_NO_ALL)) ==
308 (FLG_OFG_ENABLE | FLG_OFG_NO_ALL))
309 ofl->ofl_guideflags &= ~FLG_OFG_ENABLE;
311 if (Plibpath && (Llibdir || Ulibdir))
312 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
313 Llibdir ? 'L' : 'U');
315 if (rflag) {
316 if (dflag == SET_UNKNOWN)
317 dflag = SET_FALSE;
319 * Combining relocations when building a relocatable
320 * object isn't allowed. Warn the user, but proceed.
322 if (ofl->ofl_flags & FLG_OF_COMREL)
323 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP),
324 MSG_INTL(MSG_MARG_REL),
325 MSG_ORIG(MSG_ARG_ZCOMBRELOC));
326 ofl->ofl_flags |= FLG_OF_RELOBJ;
327 } else {
329 * Translating object capabilities to symbol capabilities is
330 * only meaningful when creating a relocatable object.
332 if (ofl->ofl_flags & FLG_OF_OTOSCAP)
333 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ONLY),
334 MSG_ORIG(MSG_ARG_ZSYMBOLCAP),
335 MSG_INTL(MSG_MARG_REL));
338 * If the user hasn't explicitly requested that relocations
339 * not be combined, combine them by default.
341 if ((ofl->ofl_flags & FLG_OF_NOCOMREL) == 0)
342 ofl->ofl_flags |= FLG_OF_COMREL;
345 if (zdflag == SET_TRUE)
346 ofl->ofl_flags |= FLG_OF_NOUNDEF;
348 if (zinflag)
349 ofl->ofl_dtflags_1 |= DF_1_INTERPOSE;
351 if (sflag)
352 ofl->ofl_flags |= FLG_OF_STRIP;
354 if (Qflag == SET_TRUE)
355 ofl->ofl_flags |= FLG_OF_ADDVERS;
357 if (Blflag)
358 ofl->ofl_flags |= FLG_OF_AUTOLCL;
360 if (Beflag)
361 ofl->ofl_flags |= FLG_OF_AUTOELM;
363 if (Blflag && Beflag)
364 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
365 MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL));
367 if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP))
368 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
369 MSG_ORIG(MSG_ARG_CI), MSG_ORIG(MSG_ARG_ZNOINTERP));
371 if ((ofl->ofl_flags1 & (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ==
372 (FLG_OF1_NRLXREL | FLG_OF1_RLXREL))
373 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
374 MSG_ORIG(MSG_ARG_ZRELAXRELOC),
375 MSG_ORIG(MSG_ARG_ZNORELAXRELOC));
377 if (ofl->ofl_filtees && !Gflag)
378 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL),
379 ((ofl->ofl_flags & FLG_OF_AUX) ?
380 MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER)));
382 if (dflag != SET_FALSE) {
384 * Set -Bdynamic on by default, setting is rechecked as input
385 * files are processed.
387 ofl->ofl_flags |=
388 (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED);
390 if (aflag)
391 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
392 MSG_ORIG(MSG_ARG_DY), MSG_ORIG(MSG_ARG_A));
394 if (bflag)
395 ofl->ofl_flags |= FLG_OF_BFLAG;
397 if (Bgflag == TRUE) {
398 if (zdflag == SET_FALSE)
399 ld_eprintf(ofl, ERR_FATAL,
400 MSG_INTL(MSG_ARG_INCOMP),
401 MSG_ORIG(MSG_ARG_BGROUP),
402 MSG_ORIG(MSG_ARG_ZNODEF));
403 ofl->ofl_dtflags_1 |= DF_1_GROUP;
404 ofl->ofl_flags |= FLG_OF_NOUNDEF;
408 * If the use of default library searching has been suppressed
409 * but no runpaths have been provided we're going to have a hard
410 * job running this object.
412 if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath)
413 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ARG_NODEFLIB),
414 MSG_INTL(MSG_MARG_RPATH));
417 * By default, text relocation warnings are given when building
418 * an executable unless the -b flag is specified. This option
419 * implies that unclean text can be created, so no warnings are
420 * generated unless specifically asked for.
422 if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) ||
423 ((ztflag == NULL) && bflag)) {
424 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
425 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
426 } else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) {
427 ofl->ofl_flags |= FLG_OF_PURETXT;
428 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
431 if (Gflag || !rflag) {
433 * Create a dynamic object. -Bdirect indicates that all
434 * references should be bound directly. This also
435 * enables lazyloading. Individual symbols can be
436 * bound directly (or not) using mapfiles and the
437 * DIRECT (NODIRECT) qualifier. With this capability,
438 * each syminfo entry is tagged SYMINFO_FLG_DIRECTBIND.
439 * Prior to this per-symbol direct binding, runtime
440 * direct binding was controlled via the DF_1_DIRECT
441 * flag. This flag affected all references from the
442 * object. -Bdirect continues to set this flag, and
443 * thus provides a means of taking a newly built
444 * direct binding object back to older systems.
446 * NOTE, any use of per-symbol NODIRECT bindings, or
447 * -znodirect, will disable the creation of the
448 * DF_1_DIRECT flag. Older runtime linkers do not
449 * have the capability to do per-symbol direct bindings.
451 if (Bdflag == SET_TRUE) {
452 ofl->ofl_dtflags_1 |= DF_1_DIRECT;
453 ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
454 ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
455 ofl->ofl_flags |= FLG_OF_SYMINFO;
459 * -Bnodirect disables directly binding to any symbols
460 * exported from the object being created. Individual
461 * references to external objects can still be affected
462 * by -zdirect or mapfile DIRECT directives.
464 if (Bdflag == SET_FALSE) {
465 ofl->ofl_flags1 |= (FLG_OF1_NDIRECT |
466 FLG_OF1_NGLBDIR | FLG_OF1_ALNODIR);
467 ofl->ofl_flags |= FLG_OF_SYMINFO;
471 if (!Gflag && !rflag) {
473 * Dynamically linked executable.
475 ofl->ofl_flags |= FLG_OF_EXEC;
477 if (zdflag != SET_FALSE)
478 ofl->ofl_flags |= FLG_OF_NOUNDEF;
481 * -z textwarn is the default for executables, and
482 * only an explicit -z text* option can change that,
483 * so there's no need to provide additional guidance.
485 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
487 if (Bsflag)
488 ld_eprintf(ofl, ERR_FATAL,
489 MSG_INTL(MSG_ARG_DY_INCOMP),
490 MSG_ORIG(MSG_ARG_BSYMBOLIC));
491 if (ofl->ofl_soname)
492 ld_eprintf(ofl, ERR_FATAL,
493 MSG_INTL(MSG_MARG_DY_INCOMP),
494 MSG_INTL(MSG_MARG_SONAME));
495 } else if (!rflag) {
497 * Shared library.
499 ofl->ofl_flags |= FLG_OF_SHAROBJ;
502 * By default, print text relocation warnings for
503 * executables but *not* for shared objects. However,
504 * if -z guidance is on, issue warnings for shared
505 * objects as well.
507 * If -z textwarn is explicitly specified, also issue
508 * guidance messages if -z guidance is on, but not
509 * for -z text or -z textoff.
511 if (ztflag == NULL) {
512 if (!OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
513 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
514 } else if ((ofl->ofl_flags & FLG_OF_PURETXT) ||
515 (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)) {
516 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
519 if (Bsflag) {
521 * -Bsymbolic, and -Bnodirect make no sense.
523 if (Bdflag == SET_FALSE)
524 ld_eprintf(ofl, ERR_FATAL,
525 MSG_INTL(MSG_ARG_INCOMP),
526 MSG_ORIG(MSG_ARG_BSYMBOLIC),
527 MSG_ORIG(MSG_ARG_BNODIRECT));
528 ofl->ofl_flags |= FLG_OF_SYMBOLIC;
529 ofl->ofl_dtflags |= DF_SYMBOLIC;
531 } else {
533 * Dynamic relocatable object.
535 if (ztflag == NULL)
536 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
537 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
539 if (ofl->ofl_interp)
540 ld_eprintf(ofl, ERR_FATAL,
541 MSG_INTL(MSG_MARG_INCOMP),
542 MSG_INTL(MSG_MARG_REL),
543 MSG_ORIG(MSG_ARG_CI));
545 } else {
546 ofl->ofl_flags |= FLG_OF_STATIC;
548 if (bflag)
549 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
550 MSG_ORIG(MSG_ARG_B));
551 if (ofl->ofl_soname)
552 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
553 MSG_INTL(MSG_MARG_SONAME));
554 if (ofl->ofl_depaudit)
555 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
556 MSG_ORIG(MSG_ARG_CP));
557 if (ofl->ofl_audit)
558 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
559 MSG_ORIG(MSG_ARG_P));
560 if (ofl->ofl_config)
561 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
562 MSG_ORIG(MSG_ARG_C));
563 if (ztflag)
564 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
565 MSG_ORIG(MSG_ARG_ZTEXTALL));
566 if (Gflag)
567 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
568 MSG_INTL(MSG_MARG_SO));
569 if (aflag && rflag)
570 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP),
571 MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL));
573 if (rflag) {
575 * We can only strip the symbol table and string table
576 * if no output relocations will refer to them.
578 if (sflag)
579 ld_eprintf(ofl, ERR_WARNING,
580 MSG_INTL(MSG_ARG_STRIP),
581 MSG_INTL(MSG_MARG_REL),
582 MSG_INTL(MSG_MARG_STRIP));
584 if (ztflag == NULL)
585 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
586 ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
588 if (ofl->ofl_interp)
589 ld_eprintf(ofl, ERR_FATAL,
590 MSG_INTL(MSG_MARG_INCOMP),
591 MSG_INTL(MSG_MARG_REL),
592 MSG_ORIG(MSG_ARG_CI));
593 } else {
595 * Static executable.
597 ofl->ofl_flags |= FLG_OF_EXEC | FLG_OF_PROCRED;
599 if (zdflag != SET_FALSE)
600 ofl->ofl_flags |= FLG_OF_NOUNDEF;
605 * If the user didn't supply an output file name supply a default.
607 if (ofl->ofl_name == NULL)
608 ofl->ofl_name = MSG_ORIG(MSG_STR_AOUT);
611 * We set the entrance criteria after all input argument processing as
612 * it is only at this point we're sure what the output image will be
613 * (static or dynamic).
615 if (ld_ent_setup(ofl, ld_targ.t_m.m_segm_align) == S_ERROR)
616 return (S_ERROR);
619 * Does the host currently running the linker have the same
620 * byte order as the target for which the object is being produced?
621 * If not, set FLG_OF1_ENCDIFF so relocation code will know
622 * to check.
624 if (_elf_sys_encoding() != ld_targ.t_m.m_data)
625 ofl->ofl_flags1 |= FLG_OF1_ENCDIFF;
628 * If the target has special executable section filling requirements,
629 * register the fill function with libelf
631 if (ld_targ.t_ff.ff_execfill != NULL)
632 _elf_execfill(ld_targ.t_ff.ff_execfill);
635 * Initialize string tables. Symbol definitions within mapfiles can
636 * result in the creation of input sections.
638 if (ld_init_strings(ofl) == S_ERROR)
639 return (S_ERROR);
642 * Process mapfiles. Mapfile can redefine or add sections/segments,
643 * so this must come after the default entrance criteria are established
644 * (above).
646 if (ofl->ofl_maps) {
647 const char *name;
648 Aliste idx;
650 for (APLIST_TRAVERSE(ofl->ofl_maps, idx, name))
651 if (!ld_map_parse(name, ofl))
652 return (S_ERROR);
654 if (!ld_map_post_process(ofl))
655 return (S_ERROR);
659 * If a mapfile has been used to define a single symbolic scope of
660 * interfaces, -Bsymbolic is established. This global setting goes
661 * beyond individual symbol protection, and ensures all relocations
662 * (even those that reference section symbols) are processed within
663 * the object being built.
665 if (((ofl->ofl_flags &
666 (FLG_OF_MAPSYMB | FLG_OF_MAPGLOB)) == FLG_OF_MAPSYMB) &&
667 (ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM))) {
668 ofl->ofl_flags |= FLG_OF_SYMBOLIC;
669 ofl->ofl_dtflags |= DF_SYMBOLIC;
673 * If -zloadfltr is set, verify that filtering is in effect. Filters
674 * are either established from the command line, and affect the whole
675 * object, or are set on a per-symbol basis from a mapfile.
677 if (zlflag) {
678 if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL))
679 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFLTR),
680 MSG_ORIG(MSG_ARG_ZLOADFLTR));
681 ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
685 * Check that we have something to work with. This check is carried out
686 * after mapfile processing as its possible a mapfile is being used to
687 * define symbols, in which case it would be sufficient to build the
688 * output file purely from the mapfile.
690 if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) {
691 if ((Vflag ||
692 (Dflag && (dbg_desc->d_extra & DBG_E_HELP_EXIT))) &&
693 (argc == 2)) {
694 ofl->ofl_flags1 |= FLG_OF1_DONE;
695 } else {
696 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFILES));
697 return (S_ERROR);
700 return (1);
704 * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
705 * used as an argument to getopt().
707 * If the second argument 'usage' is not NULL, then this is called from the
708 * first pass. Else this is called from the second pass.
710 static uintptr_t
711 createargv(Ofl_desc *ofl, int *usage)
713 int argc = 0, idx = 0, ooptind;
714 uintptr_t ret;
715 char **argv, *p0;
718 * The argument being examined is either:
719 * ld32= or
720 * ld64=
722 #if defined(_LP64)
723 if (optarg[2] == '3')
724 return (0);
725 #else
726 if (optarg[2] == '6')
727 return (0);
728 #endif
730 p0 = &optarg[5];
733 * Count the number of arguments.
735 while (*p0) {
737 * Pointing at non-separator character.
739 if (*p0 != ',') {
740 argc++;
741 while (*p0 && (*p0 != ','))
742 p0++;
743 continue;
747 * Pointing at a separator character.
749 if (*p0 == ',') {
750 while (*p0 == ',')
751 p0++;
752 continue;
756 if (argc == 0)
757 return (0);
760 * Allocate argument vector.
762 if ((p0 = (char *)strdup(&optarg[5])) == NULL)
763 return (S_ERROR);
764 if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == NULL)
765 return (S_ERROR);
767 while (*p0) {
768 char *p;
771 * Pointing at the beginning of non-separator character string.
773 if (*p0 != ',') {
774 p = p0;
775 while (*p0 && (*p0 != ','))
776 p0++;
777 argv[idx++] = p;
778 if (*p0) {
779 *p0 = '\0';
780 p0++;
782 continue;
786 * Pointing at the beginining of separator character string.
788 if (*p0 == ',') {
789 while (*p0 == ',')
790 p0++;
791 continue;
794 argv[idx] = 0;
795 ooptind = optind;
796 optind = 0;
799 * Dispatch to pass1 or pass2
801 if (usage)
802 ret = process_flags_com(ofl, argc, argv, usage);
803 else
804 ret = process_files_com(ofl, argc, argv);
806 optind = ooptind;
807 return (ret);
811 * Parse the items in a '-z guidance' value, and set the ofl_guideflags.
812 * A guidance option looks like this:
814 * -z guidance[=item1,item2,...]
816 * Where each item specifies categories of guidance messages to suppress,
817 * each starting with the prefix 'no'. We allow arbitrary whitespace between
818 * the items, allow multiple ',' delimiters without an intervening item, and
819 * quietly ignore any items we don't recognize.
821 * - Such items are likely to be known to newer versions of the linker,
822 * and we do not want an older version of the linker to
823 * complain about them.
825 * - Times and standards can change, and so we wish to reserve the
826 * right to make an old item that no longer makes sense go away.
827 * Quietly ignoring unrecognized items facilitates this.
829 * However, we always display unrecognized items in debug output.
831 * entry:
832 * ofl - Output descriptor
833 * optarg - option string to be processed. This will either be a NULL
834 * terminated 'guidance', or it will be 'guidance=' followed
835 * by the item tokens as described above.
837 * exit:
838 * Returns TRUE (1) on success, FALSE (0) on failure.
841 static Boolean
842 guidance_parse(Ofl_desc *ofl, char *optarg)
844 typedef struct {
845 const char *name;
846 ofl_guideflag_t flag;
847 } item_desc;
849 static item_desc items[] = {
850 { MSG_ORIG(MSG_ARG_GUIDE_NO_ALL), FLG_OFG_NO_ALL },
852 { MSG_ORIG(MSG_ARG_GUIDE_NO_DEFS), FLG_OFG_NO_DEFS },
853 { MSG_ORIG(MSG_ARG_GUIDE_NO_DIRECT), FLG_OFG_NO_DB },
854 { MSG_ORIG(MSG_ARG_GUIDE_NO_LAZYLOAD), FLG_OFG_NO_LAZY },
855 { MSG_ORIG(MSG_ARG_GUIDE_NO_MAPFILE), FLG_OFG_NO_MF },
856 { MSG_ORIG(MSG_ARG_GUIDE_NO_TEXT), FLG_OFG_NO_TEXT },
857 { MSG_ORIG(MSG_ARG_GUIDE_NO_UNUSED), FLG_OFG_NO_UNUSED },
858 { NULL, 0 }
861 char *lasts, *name;
862 item_desc *item;
863 ofl_guideflag_t ofl_guideflags = FLG_OFG_ENABLE;
866 * Skip the 'guidance' prefix. If NULL terminated, there are no
867 * item values to parse. Otherwise, skip the '=' and parse the items.
869 optarg += MSG_ARG_GUIDE_SIZE;
870 if (*optarg == '=') {
871 optarg++;
873 if ((name = libld_malloc(strlen(optarg) + 1)) == NULL)
874 return (FALSE);
875 (void) strcpy(name, optarg);
877 if ((name = strtok_r(name, MSG_ORIG(MSG_ARG_GUIDE_DELIM),
878 &lasts)) != NULL) {
879 do {
880 for (item = items; item->name != NULL; item++)
881 if (strcasecmp(name, item->name) == 0)
882 break;
883 if (item->name == NULL) {
884 DBG_CALL(Dbg_args_guidance_unknown(
885 ofl->ofl_lml, name));
886 continue;
888 ofl_guideflags |= item->flag;
889 } while ((name = strtok_r(NULL,
890 MSG_ORIG(MSG_ARG_GUIDE_DELIM), &lasts)) != NULL);
895 * If -zguidance is used more than once, we take the first one. We
896 * do this quietly if they have identical options, and with a warning
897 * otherwise.
899 if ((initial_guidance_flags & FLG_OFG_ENABLE) &&
900 (ofl_guideflags != initial_guidance_flags)) {
901 ld_eprintf(ofl, ERR_WARNING_NF, MSG_INTL(MSG_ARG_MTONCE),
902 MSG_ORIG(MSG_ARG_ZGUIDE));
903 return (TRUE);
907 * First time: Save the flags for comparison to any subsequent
908 * -z guidance that comes along, and OR the resulting flags into
909 * the flags kept in the output descriptor.
911 initial_guidance_flags = ofl_guideflags;
912 ofl->ofl_guideflags |= ofl_guideflags;
913 return (TRUE);
917 * Parse the -z assert-deflib option. This option can appear in two different
918 * forms:
919 * -z assert-deflib
920 * -z assert-deflib=libfred.so
922 * Either form enables this option, the latter form marks libfred.so as an
923 * exempt library from the check. It is valid to have multiple invocations of
924 * the second form. We silently ignore mulitple occurrences of the first form
925 * and multiple invocations of the first form when the second form also occurs.
927 * We only return false when we have an internal error, such as the failure of
928 * aplist_append. Every other time we return true, but we have the appropriate
929 * fatal flags set beacuse of the ld_eprintf.
931 static int
932 assdeflib_parse(Ofl_desc *ofl, char *optarg)
934 size_t olen, mlen;
935 ofl->ofl_flags |= FLG_OF_ADEFLIB;
937 olen = strlen(optarg);
938 /* Minimum size of assert-deflib=lib%s.so */
939 mlen = MSG_ARG_ASSDEFLIB_SIZE + 1 + MSG_STR_LIB_SIZE +
940 MSG_STR_SOEXT_SIZE;
941 if (olen > MSG_ARG_ASSDEFLIB_SIZE) {
942 if (optarg[MSG_ARG_ASSDEFLIB_SIZE] != '=') {
943 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ILLEGAL),
944 MSG_ORIG(MSG_ARG_ASSDEFLIB), optarg);
945 return (TRUE);
948 if (strncmp(optarg + MSG_ARG_ASSDEFLIB_SIZE + 1,
949 MSG_ORIG(MSG_STR_LIB), MSG_STR_LIB_SIZE) != 0 ||
950 strcmp(optarg + olen - MSG_STR_SOEXT_SIZE,
951 MSG_ORIG(MSG_STR_SOEXT)) != 0 || olen <= mlen) {
952 ld_eprintf(ofl, ERR_FATAL,
953 MSG_INTL(MSG_ARG_ASSDEFLIB_MALFORMED), optarg);
954 return (TRUE);
957 if (aplist_append(&ofl->ofl_assdeflib, optarg +
958 MSG_ARG_ASSDEFLIB_SIZE + 1, AL_CNT_ASSDEFLIB) == NULL)
959 return (FALSE);
962 return (TRUE);
965 static int optitle = 0;
967 * Parsing options pass1 for process_flags().
969 static uintptr_t
970 parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
972 int c, ndx = optind;
975 * The -32, -64 and -ztarget options are special, in that we validate
976 * them, but otherwise ignore them. libld.so (this code) is called
977 * from the ld front end program. ld has already examined the
978 * arguments to determine the output class and machine type of the
979 * output object, as reflected in the version (32/64) of ld_main()
980 * that was called and the value of the 'mach' argument passed.
981 * By time execution reaches this point, these options have already
982 * been seen and acted on.
984 while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
986 switch (c) {
987 case '3':
988 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
991 * -32 is processed by ld to determine the output class.
992 * Here we sanity check the option incase some other
993 * -3* option is mistakenly passed to us.
995 if (optarg[0] != '2')
996 ld_eprintf(ofl, ERR_FATAL,
997 MSG_INTL(MSG_ARG_ILLEGAL),
998 MSG_ORIG(MSG_ARG_3), optarg);
999 continue;
1001 case '6':
1002 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1005 * -64 is processed by ld to determine the output class.
1006 * Here we sanity check the option incase some other
1007 * -6* option is mistakenly passed to us.
1009 if (optarg[0] != '4')
1010 ld_eprintf(ofl, ERR_FATAL,
1011 MSG_INTL(MSG_ARG_ILLEGAL),
1012 MSG_ORIG(MSG_ARG_6), optarg);
1013 continue;
1015 case 'a':
1016 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1017 aflag = TRUE;
1018 break;
1020 case 'b':
1021 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1022 bflag = TRUE;
1025 * This is a hack, and may be undone later.
1026 * The -b option is only used to build the Unix
1027 * kernel and its related kernel-mode modules.
1028 * We do not want those files to get a .SUNW_ldynsym
1029 * section. At least for now, the kernel makes no
1030 * use of .SUNW_ldynsym, and we do not want to use
1031 * the space to hold it. Therefore, we overload
1032 * the use of -b to also imply -znoldynsym.
1034 ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1035 break;
1037 case 'c':
1038 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1039 if (ofl->ofl_config)
1040 ld_eprintf(ofl, ERR_WARNING_NF,
1041 MSG_INTL(MSG_ARG_MTONCE),
1042 MSG_ORIG(MSG_ARG_C));
1043 else
1044 ofl->ofl_config = optarg;
1045 break;
1047 case 'C':
1048 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1049 demangle_flag = 1;
1050 break;
1052 case 'd':
1053 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1054 if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1055 if (dflag != SET_UNKNOWN)
1056 ld_eprintf(ofl, ERR_WARNING_NF,
1057 MSG_INTL(MSG_ARG_MTONCE),
1058 MSG_ORIG(MSG_ARG_D));
1059 else
1060 dflag = SET_FALSE;
1061 } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1062 if (dflag != SET_UNKNOWN)
1063 ld_eprintf(ofl, ERR_WARNING_NF,
1064 MSG_INTL(MSG_ARG_MTONCE),
1065 MSG_ORIG(MSG_ARG_D));
1066 else
1067 dflag = SET_TRUE;
1068 } else {
1069 ld_eprintf(ofl, ERR_FATAL,
1070 MSG_INTL(MSG_ARG_ILLEGAL),
1071 MSG_ORIG(MSG_ARG_D), optarg);
1073 break;
1075 case 'e':
1076 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1077 if (ofl->ofl_entry)
1078 ld_eprintf(ofl, ERR_WARNING_NF,
1079 MSG_INTL(MSG_MARG_MTONCE),
1080 MSG_INTL(MSG_MARG_ENTRY));
1081 else
1082 ofl->ofl_entry = (void *)optarg;
1083 break;
1085 case 'f':
1086 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1087 if (ofl->ofl_filtees &&
1088 (!(ofl->ofl_flags & FLG_OF_AUX))) {
1089 ld_eprintf(ofl, ERR_FATAL,
1090 MSG_INTL(MSG_MARG_INCOMP),
1091 MSG_INTL(MSG_MARG_FILTER_AUX),
1092 MSG_INTL(MSG_MARG_FILTER));
1093 } else {
1094 if ((ofl->ofl_filtees =
1095 add_string(ofl->ofl_filtees, optarg)) ==
1096 (const char *)S_ERROR)
1097 return (S_ERROR);
1098 ofl->ofl_flags |= FLG_OF_AUX;
1100 break;
1102 case 'F':
1103 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1104 if (ofl->ofl_filtees &&
1105 (ofl->ofl_flags & FLG_OF_AUX)) {
1106 ld_eprintf(ofl, ERR_FATAL,
1107 MSG_INTL(MSG_MARG_INCOMP),
1108 MSG_INTL(MSG_MARG_FILTER),
1109 MSG_INTL(MSG_MARG_FILTER_AUX));
1110 } else {
1111 if ((ofl->ofl_filtees =
1112 add_string(ofl->ofl_filtees, optarg)) ==
1113 (const char *)S_ERROR)
1114 return (S_ERROR);
1116 break;
1118 case 'h':
1119 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1120 if (ofl->ofl_soname)
1121 ld_eprintf(ofl, ERR_WARNING_NF,
1122 MSG_INTL(MSG_MARG_MTONCE),
1123 MSG_INTL(MSG_MARG_SONAME));
1124 else
1125 ofl->ofl_soname = (const char *)optarg;
1126 break;
1128 case 'i':
1129 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1130 ofl->ofl_flags |= FLG_OF_IGNENV;
1131 break;
1133 case 'I':
1134 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1135 if (ofl->ofl_interp)
1136 ld_eprintf(ofl, ERR_WARNING_NF,
1137 MSG_INTL(MSG_ARG_MTONCE),
1138 MSG_ORIG(MSG_ARG_CI));
1139 else
1140 ofl->ofl_interp = (const char *)optarg;
1141 break;
1143 case 'l':
1144 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1146 * For now, count any library as a shared object. This
1147 * is used to size the internal symbol cache. This
1148 * value is recalculated later on actual file processing
1149 * to get an accurate shared object count.
1151 ofl->ofl_soscnt++;
1152 break;
1154 case 'm':
1155 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1156 ofl->ofl_flags |= FLG_OF_GENMAP;
1157 break;
1159 case 'o':
1160 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1161 if (ofl->ofl_name)
1162 ld_eprintf(ofl, ERR_WARNING_NF,
1163 MSG_INTL(MSG_MARG_MTONCE),
1164 MSG_INTL(MSG_MARG_OUTFILE));
1165 else
1166 ofl->ofl_name = (const char *)optarg;
1167 break;
1169 case 'p':
1170 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1173 * Multiple instances of this option may occur. Each
1174 * additional instance is effectively concatenated to
1175 * the previous separated by a colon.
1177 if (*optarg != '\0') {
1178 if ((ofl->ofl_audit =
1179 add_string(ofl->ofl_audit,
1180 optarg)) == (const char *)S_ERROR)
1181 return (S_ERROR);
1183 break;
1185 case 'P':
1186 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1189 * Multiple instances of this option may occur. Each
1190 * additional instance is effectively concatenated to
1191 * the previous separated by a colon.
1193 if (*optarg != '\0') {
1194 if ((ofl->ofl_depaudit =
1195 add_string(ofl->ofl_depaudit,
1196 optarg)) == (const char *)S_ERROR)
1197 return (S_ERROR);
1199 break;
1201 case 'r':
1202 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1203 rflag = TRUE;
1204 break;
1206 case 'R':
1207 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1210 * Multiple instances of this option may occur. Each
1211 * additional instance is effectively concatenated to
1212 * the previous separated by a colon.
1214 if (*optarg != '\0') {
1215 if ((ofl->ofl_rpath =
1216 add_string(ofl->ofl_rpath,
1217 optarg)) == (const char *)S_ERROR)
1218 return (S_ERROR);
1220 break;
1222 case 's':
1223 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1224 sflag = TRUE;
1225 break;
1227 case 't':
1228 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1229 ofl->ofl_flags |= FLG_OF_NOWARN;
1230 break;
1232 case 'u':
1233 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1234 break;
1236 case 'z':
1237 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1240 * For specific help, print our usage message and exit
1241 * immediately to ensure a 0 return code.
1243 if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
1244 MSG_ARG_HELP_SIZE) == 0) {
1245 usage_mesg(TRUE);
1246 exit(0);
1250 * For some options set a flag - further consistancy
1251 * checks will be carried out in check_flags().
1253 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1254 MSG_ARG_LD32_SIZE) == 0) ||
1255 (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1256 MSG_ARG_LD64_SIZE) == 0)) {
1257 if (createargv(ofl, usage) == S_ERROR)
1258 return (S_ERROR);
1260 } else if (
1261 strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
1262 if (zdflag != SET_UNKNOWN)
1263 ld_eprintf(ofl, ERR_WARNING_NF,
1264 MSG_INTL(MSG_ARG_MTONCE),
1265 MSG_ORIG(MSG_ARG_ZDEFNODEF));
1266 else
1267 zdflag = SET_TRUE;
1268 ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1269 } else if (strcmp(optarg,
1270 MSG_ORIG(MSG_ARG_NODEFS)) == 0) {
1271 if (zdflag != SET_UNKNOWN)
1272 ld_eprintf(ofl, ERR_WARNING_NF,
1273 MSG_INTL(MSG_ARG_MTONCE),
1274 MSG_ORIG(MSG_ARG_ZDEFNODEF));
1275 else
1276 zdflag = SET_FALSE;
1277 ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
1278 } else if (strcmp(optarg,
1279 MSG_ORIG(MSG_ARG_TEXT)) == 0) {
1280 if (ztflag &&
1281 (ztflag != MSG_ORIG(MSG_ARG_ZTEXT)))
1282 ld_eprintf(ofl, ERR_FATAL,
1283 MSG_INTL(MSG_ARG_INCOMP),
1284 MSG_ORIG(MSG_ARG_ZTEXT),
1285 ztflag);
1286 ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
1287 } else if (strcmp(optarg,
1288 MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
1289 if (ztflag &&
1290 (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF)))
1291 ld_eprintf(ofl, ERR_FATAL,
1292 MSG_INTL(MSG_ARG_INCOMP),
1293 MSG_ORIG(MSG_ARG_ZTEXTOFF),
1294 ztflag);
1295 ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
1296 } else if (strcmp(optarg,
1297 MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
1298 if (ztflag &&
1299 (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN)))
1300 ld_eprintf(ofl, ERR_FATAL,
1301 MSG_INTL(MSG_ARG_INCOMP),
1302 MSG_ORIG(MSG_ARG_ZTEXTWARN),
1303 ztflag);
1304 ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
1307 * For other options simply set the ofl flags directly.
1309 } else if (strcmp(optarg,
1310 MSG_ORIG(MSG_ARG_RESCAN)) == 0) {
1311 ofl->ofl_flags1 |= FLG_OF1_RESCAN;
1312 } else if (strcmp(optarg,
1313 MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) {
1314 ofl->ofl_flags1 |= FLG_OF1_ABSEXEC;
1315 } else if (strcmp(optarg,
1316 MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) {
1317 zlflag = TRUE;
1318 } else if (strcmp(optarg,
1319 MSG_ORIG(MSG_ARG_NORELOC)) == 0) {
1320 ofl->ofl_dtflags_1 |= DF_1_NORELOC;
1321 } else if (strcmp(optarg,
1322 MSG_ORIG(MSG_ARG_NOVERSION)) == 0) {
1323 ofl->ofl_flags |= FLG_OF_NOVERSEC;
1324 } else if (strcmp(optarg,
1325 MSG_ORIG(MSG_ARG_MULDEFS)) == 0) {
1326 ofl->ofl_flags |= FLG_OF_MULDEFS;
1327 } else if (strcmp(optarg,
1328 MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) {
1329 ofl->ofl_flags |= FLG_OF_REDLSYM;
1330 } else if (strcmp(optarg,
1331 MSG_ORIG(MSG_ARG_INITFIRST)) == 0) {
1332 ofl->ofl_dtflags_1 |= DF_1_INITFIRST;
1333 } else if (strcmp(optarg,
1334 MSG_ORIG(MSG_ARG_NODELETE)) == 0) {
1335 ofl->ofl_dtflags_1 |= DF_1_NODELETE;
1336 } else if (strcmp(optarg,
1337 MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) {
1338 ofl->ofl_flags1 |= FLG_OF1_NOPARTI;
1339 } else if (strcmp(optarg,
1340 MSG_ORIG(MSG_ARG_NOOPEN)) == 0) {
1341 ofl->ofl_dtflags_1 |= DF_1_NOOPEN;
1342 } else if (strcmp(optarg,
1343 MSG_ORIG(MSG_ARG_NOW)) == 0) {
1344 ofl->ofl_dtflags_1 |= DF_1_NOW;
1345 ofl->ofl_dtflags |= DF_BIND_NOW;
1346 } else if (strcmp(optarg,
1347 MSG_ORIG(MSG_ARG_ORIGIN)) == 0) {
1348 ofl->ofl_dtflags_1 |= DF_1_ORIGIN;
1349 ofl->ofl_dtflags |= DF_ORIGIN;
1350 } else if (strcmp(optarg,
1351 MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) {
1352 ofl->ofl_dtflags_1 |= DF_1_NODEFLIB;
1353 } else if (strcmp(optarg,
1354 MSG_ORIG(MSG_ARG_NODUMP)) == 0) {
1355 ofl->ofl_dtflags_1 |= DF_1_NODUMP;
1356 } else if (strcmp(optarg,
1357 MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) {
1358 ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE;
1359 } else if (strcmp(optarg,
1360 MSG_ORIG(MSG_ARG_VERBOSE)) == 0) {
1361 ofl->ofl_flags |= FLG_OF_VERBOSE;
1362 } else if (strcmp(optarg,
1363 MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) {
1364 ofl->ofl_flags |= FLG_OF_COMREL;
1365 } else if (strcmp(optarg,
1366 MSG_ORIG(MSG_ARG_NOCOMBRELOC)) == 0) {
1367 ofl->ofl_flags |= FLG_OF_NOCOMREL;
1368 } else if (strcmp(optarg,
1369 MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) {
1370 ofl->ofl_flags1 |= FLG_OF1_NCSTTAB;
1371 } else if (strcmp(optarg,
1372 MSG_ORIG(MSG_ARG_NOINTERP)) == 0) {
1373 ofl->ofl_flags1 |= FLG_OF1_NOINTRP;
1374 } else if (strcmp(optarg,
1375 MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) {
1376 zinflag = TRUE;
1377 } else if (strcmp(optarg,
1378 MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1379 ofl->ofl_flags1 |= FLG_OF1_IGNPRC;
1380 } else if (strcmp(optarg,
1381 MSG_ORIG(MSG_ARG_RELAXRELOC)) == 0) {
1382 ofl->ofl_flags1 |= FLG_OF1_RLXREL;
1383 } else if (strcmp(optarg,
1384 MSG_ORIG(MSG_ARG_NORELAXRELOC)) == 0) {
1385 ofl->ofl_flags1 |= FLG_OF1_NRLXREL;
1386 } else if (strcmp(optarg,
1387 MSG_ORIG(MSG_ARG_NOLDYNSYM)) == 0) {
1388 ofl->ofl_flags |= FLG_OF_NOLDYNSYM;
1389 } else if (strcmp(optarg,
1390 MSG_ORIG(MSG_ARG_GLOBAUDIT)) == 0) {
1391 ofl->ofl_dtflags_1 |= DF_1_GLOBAUDIT;
1392 } else if (strcmp(optarg,
1393 MSG_ORIG(MSG_ARG_NOSIGHANDLER)) == 0) {
1394 ofl->ofl_flags1 |= FLG_OF1_NOSGHND;
1395 } else if (strcmp(optarg,
1396 MSG_ORIG(MSG_ARG_SYMBOLCAP)) == 0) {
1397 ofl->ofl_flags |= FLG_OF_OTOSCAP;
1400 * Check archive group usage
1401 * -z rescan-start ... -z rescan-end
1402 * to ensure they don't overlap and are well formed.
1404 } else if (strcmp(optarg,
1405 MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1406 if (ofl->ofl_ars_gsandx == 0) {
1407 ofl->ofl_ars_gsandx = ndx;
1408 } else if (ofl->ofl_ars_gsandx > 0) {
1409 /* Another group is still open */
1410 ld_eprintf(ofl, ERR_FATAL,
1411 MSG_INTL(MSG_ARG_AR_GRP_OLAP),
1412 MSG_INTL(MSG_MARG_AR_GRPS));
1413 /* Don't report cascading errors */
1414 ofl->ofl_ars_gsandx = -1;
1416 } else if (strcmp(optarg,
1417 MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1418 if (ofl->ofl_ars_gsandx > 0) {
1419 ofl->ofl_ars_gsandx = 0;
1420 } else if (ofl->ofl_ars_gsandx == 0) {
1421 /* There was no matching begin */
1422 ld_eprintf(ofl, ERR_FATAL,
1423 MSG_INTL(MSG_ARG_AR_GRP_BAD),
1424 MSG_INTL(MSG_MARG_AR_GRP_END),
1425 MSG_INTL(MSG_MARG_AR_GRP_START));
1426 /* Don't report cascading errors */
1427 ofl->ofl_ars_gsandx = -1;
1431 * If -z wrap is seen, enter the symbol to be wrapped
1432 * into the wrap AVL tree.
1434 } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_WRAP),
1435 MSG_ARG_WRAP_SIZE) == 0) {
1436 if (ld_wrap_enter(ofl,
1437 optarg + MSG_ARG_WRAP_SIZE) == NULL)
1438 return (S_ERROR);
1439 } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASLR),
1440 MSG_ARG_ASLR_SIZE) == 0) {
1441 char *p = optarg + MSG_ARG_ASLR_SIZE;
1442 if (*p == '\0') {
1443 ofl->ofl_aslr = 1;
1444 } else if (*p == '=') {
1445 p++;
1447 if (strcmp(p,
1448 MSG_ORIG(MSG_ARG_ENABLED)) == 0) {
1449 ofl->ofl_aslr = 1;
1450 } else if (strcmp(p,
1451 MSG_ORIG(MSG_ARG_DISABLED)) == 0) {
1452 ofl->ofl_aslr = -1;
1453 } else {
1454 ld_eprintf(ofl, ERR_FATAL,
1455 MSG_INTL(MSG_ARG_ILLEGAL),
1456 MSG_ORIG(MSG_ARG_ZASLR), p);
1457 return (S_ERROR);
1459 } else {
1460 ld_eprintf(ofl, ERR_FATAL,
1461 MSG_INTL(MSG_ARG_ILLEGAL),
1462 MSG_ORIG(MSG_ARG_Z), optarg);
1463 return (S_ERROR);
1465 } else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
1466 MSG_ARG_GUIDE_SIZE) == 0) &&
1467 ((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
1468 (optarg[MSG_ARG_GUIDE_SIZE] == '\0'))) {
1469 if (!guidance_parse(ofl, optarg))
1470 return (S_ERROR);
1471 } else if (strcmp(optarg,
1472 MSG_ORIG(MSG_ARG_FATWARN)) == 0) {
1473 if (zfwflag == SET_FALSE) {
1474 ld_eprintf(ofl, ERR_WARNING_NF,
1475 MSG_INTL(MSG_ARG_MTONCE),
1476 MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1477 } else {
1478 zfwflag = SET_TRUE;
1479 ofl->ofl_flags |= FLG_OF_FATWARN;
1481 } else if (strcmp(optarg,
1482 MSG_ORIG(MSG_ARG_NOFATWARN)) == 0) {
1483 if (zfwflag == SET_TRUE)
1484 ld_eprintf(ofl, ERR_WARNING_NF,
1485 MSG_INTL(MSG_ARG_MTONCE),
1486 MSG_ORIG(MSG_ARG_ZFATWNOFATW));
1487 else
1488 zfwflag = SET_FALSE;
1491 * Process everything related to -z assert-deflib. This
1492 * must be done in pass 1 because it gets used in pass
1493 * 2.
1495 } else if (strncmp(optarg, MSG_ORIG(MSG_ARG_ASSDEFLIB),
1496 MSG_ARG_ASSDEFLIB_SIZE) == 0) {
1497 if (assdeflib_parse(ofl, optarg) != TRUE)
1498 return (S_ERROR);
1500 * The following options just need validation as they
1501 * are interpreted on the second pass through the
1502 * command line arguments.
1504 } else if (
1505 strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY),
1506 MSG_ARG_INITARRAY_SIZE) &&
1507 strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY),
1508 MSG_ARG_FINIARRAY_SIZE) &&
1509 strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY),
1510 MSG_ARG_PREINITARRAY_SIZE) &&
1511 strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO),
1512 MSG_ARG_RTLDINFO_SIZE) &&
1513 strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE),
1514 MSG_ARG_DTRACE_SIZE) &&
1515 strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) &&
1516 strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) &&
1517 strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) &&
1518 strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) &&
1519 strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) &&
1520 strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) &&
1521 strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
1522 strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
1523 strcmp(optarg, MSG_ORIG(MSG_ARG_NODEFERRED)) &&
1524 strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
1525 strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
1526 strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) &&
1527 strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET),
1528 MSG_ARG_TARGET_SIZE) &&
1529 strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
1530 strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
1531 ld_eprintf(ofl, ERR_FATAL,
1532 MSG_INTL(MSG_ARG_ILLEGAL),
1533 MSG_ORIG(MSG_ARG_Z), optarg);
1536 break;
1538 case 'D':
1540 * If we have not yet read any input files go ahead
1541 * and process any debugging options (this allows any
1542 * argument processing, entrance criteria and library
1543 * initialization to be displayed). Otherwise, if an
1544 * input file has been seen, skip interpretation until
1545 * process_files (this allows debugging to be turned
1546 * on and off around individual groups of files).
1548 Dflag = 1;
1549 if (ofl->ofl_objscnt == 0) {
1550 if (dbg_setup(ofl, optarg, 2) == 0)
1551 return (S_ERROR);
1555 * A diagnostic can only be provided after dbg_setup().
1556 * As this is the first diagnostic that can be produced
1557 * by ld(1), issue a title for timing and basic output.
1559 if ((optitle == 0) && DBG_ENABLED) {
1560 optitle++;
1561 DBG_CALL(Dbg_basic_options(ofl->ofl_lml));
1563 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1564 break;
1566 case 'B':
1567 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1568 if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1569 if (Bdflag == SET_FALSE) {
1570 ld_eprintf(ofl, ERR_FATAL,
1571 MSG_INTL(MSG_ARG_INCOMP),
1572 MSG_ORIG(MSG_ARG_BNODIRECT),
1573 MSG_ORIG(MSG_ARG_BDIRECT));
1574 } else {
1575 Bdflag = SET_TRUE;
1576 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1578 } else if (strcmp(optarg,
1579 MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1580 if (Bdflag == SET_TRUE) {
1581 ld_eprintf(ofl, ERR_FATAL,
1582 MSG_INTL(MSG_ARG_INCOMP),
1583 MSG_ORIG(MSG_ARG_BDIRECT),
1584 MSG_ORIG(MSG_ARG_BNODIRECT));
1585 } else {
1586 Bdflag = SET_FALSE;
1587 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1589 } else if (strcmp(optarg,
1590 MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
1591 Bsflag = TRUE;
1592 else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0)
1593 ofl->ofl_flags |= FLG_OF_PROCRED;
1594 else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0)
1595 Blflag = TRUE;
1596 else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0)
1597 Bgflag = TRUE;
1598 else if (strcmp(optarg,
1599 MSG_ORIG(MSG_STR_ELIMINATE)) == 0)
1600 Beflag = TRUE;
1601 else if (strcmp(optarg,
1602 MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
1603 ld_eprintf(ofl, ERR_WARNING,
1604 MSG_INTL(MSG_ARG_UNSUPPORTED),
1605 MSG_ORIG(MSG_ARG_BTRANSLATOR));
1606 } else if (strcmp(optarg,
1607 MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
1608 strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
1609 ld_eprintf(ofl, ERR_FATAL,
1610 MSG_INTL(MSG_ARG_ILLEGAL),
1611 MSG_ORIG(MSG_ARG_CB), optarg);
1613 break;
1615 case 'G':
1616 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1617 Gflag = TRUE;
1618 break;
1620 case 'L':
1621 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1622 break;
1624 case 'M':
1625 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1626 if (aplist_append(&(ofl->ofl_maps), optarg,
1627 AL_CNT_OFL_MAPFILES) == NULL)
1628 return (S_ERROR);
1629 break;
1631 case 'N':
1632 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1633 break;
1635 case 'Q':
1636 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1637 if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
1638 if (Qflag != SET_UNKNOWN)
1639 ld_eprintf(ofl, ERR_WARNING_NF,
1640 MSG_INTL(MSG_ARG_MTONCE),
1641 MSG_ORIG(MSG_ARG_CQ));
1642 else
1643 Qflag = SET_FALSE;
1644 } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
1645 if (Qflag != SET_UNKNOWN)
1646 ld_eprintf(ofl, ERR_WARNING_NF,
1647 MSG_INTL(MSG_ARG_MTONCE),
1648 MSG_ORIG(MSG_ARG_CQ));
1649 else
1650 Qflag = SET_TRUE;
1651 } else {
1652 ld_eprintf(ofl, ERR_FATAL,
1653 MSG_INTL(MSG_ARG_ILLEGAL),
1654 MSG_ORIG(MSG_ARG_CQ), optarg);
1656 break;
1658 case 'S':
1659 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1660 if (aplist_append(&lib_support, optarg,
1661 AL_CNT_SUPPORT) == NULL)
1662 return (S_ERROR);
1663 break;
1665 case 'V':
1666 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1667 if (!Vflag)
1668 (void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL),
1669 ofl->ofl_sgsid);
1670 Vflag = TRUE;
1671 break;
1673 case 'Y':
1674 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
1675 if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
1676 if (Llibdir)
1677 ld_eprintf(ofl, ERR_WARNING_NF,
1678 MSG_INTL(MSG_ARG_MTONCE),
1679 MSG_ORIG(MSG_ARG_CYL));
1680 else
1681 Llibdir = optarg + 2;
1682 } else if (strncmp(optarg,
1683 MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
1684 if (Ulibdir)
1685 ld_eprintf(ofl, ERR_WARNING_NF,
1686 MSG_INTL(MSG_ARG_MTONCE),
1687 MSG_ORIG(MSG_ARG_CYU));
1688 else
1689 Ulibdir = optarg + 2;
1690 } else if (strncmp(optarg,
1691 MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
1692 if (Plibpath)
1693 ld_eprintf(ofl, ERR_WARNING_NF,
1694 MSG_INTL(MSG_ARG_MTONCE),
1695 MSG_ORIG(MSG_ARG_CYP));
1696 else
1697 Plibpath = optarg + 2;
1698 } else {
1699 ld_eprintf(ofl, ERR_FATAL,
1700 MSG_INTL(MSG_ARG_ILLEGAL),
1701 MSG_ORIG(MSG_ARG_CY), optarg);
1703 break;
1705 case '?':
1706 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
1708 * If the option character is '-', we're looking at a
1709 * long option which couldn't be translated, display a
1710 * more useful error.
1712 if (optopt == '-') {
1713 eprintf(ofl->ofl_lml, ERR_FATAL,
1714 MSG_INTL(MSG_ARG_LONG_UNKNOWN),
1715 argv[optind-1]);
1716 } else {
1717 eprintf(ofl->ofl_lml, ERR_FATAL,
1718 MSG_INTL(MSG_ARG_UNKNOWN), optopt);
1720 (*usage)++;
1721 break;
1723 default:
1724 break;
1728 * Update the argument index for the next getopt() iteration.
1730 ndx = optind;
1732 return (1);
1736 * Parsing options pass2 for
1738 static uintptr_t
1739 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv)
1741 int c, ndx = optind;
1743 while ((c = ld_getopt(ofl->ofl_lml, ndx, argc, argv)) != -1) {
1744 Ifl_desc *ifl;
1745 Sym_desc *sdp;
1747 switch (c) {
1748 case 'l':
1749 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1750 optarg));
1751 if (ld_find_library(optarg, ofl) == S_ERROR)
1752 return (S_ERROR);
1753 break;
1754 case 'B':
1755 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1756 optarg));
1757 if (strcmp(optarg,
1758 MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) {
1759 if (ofl->ofl_flags & FLG_OF_DYNAMIC)
1760 ofl->ofl_flags |=
1761 FLG_OF_DYNLIBS;
1762 else {
1763 ld_eprintf(ofl, ERR_FATAL,
1764 MSG_INTL(MSG_ARG_ST_INCOMP),
1765 MSG_ORIG(MSG_ARG_BDYNAMIC));
1767 } else if (strcmp(optarg,
1768 MSG_ORIG(MSG_ARG_STATIC)) == 0)
1769 ofl->ofl_flags &= ~FLG_OF_DYNLIBS;
1770 break;
1771 case 'L':
1772 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1773 optarg));
1774 if (ld_add_libdir(ofl, optarg) == S_ERROR)
1775 return (S_ERROR);
1776 break;
1777 case 'N':
1778 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1779 optarg));
1781 * Record DT_NEEDED string
1783 if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
1784 ld_eprintf(ofl, ERR_FATAL,
1785 MSG_INTL(MSG_ARG_ST_INCOMP),
1786 MSG_ORIG(MSG_ARG_CN));
1787 if (((ifl = libld_calloc(1,
1788 sizeof (Ifl_desc))) == NULL) ||
1789 (aplist_append(&ofl->ofl_sos, ifl,
1790 AL_CNT_OFL_LIBS) == NULL))
1791 return (S_ERROR);
1793 ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND);
1794 ifl->ifl_soname = optarg;
1795 ifl->ifl_flags = (FLG_IF_NEEDSTR |
1796 FLG_IF_FILEREF | FLG_IF_DEPREQD);
1798 break;
1799 case 'D':
1800 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1801 optarg));
1802 (void) dbg_setup(ofl, optarg, 3);
1803 break;
1804 case 'u':
1805 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1806 optarg));
1807 if (ld_sym_add_u(optarg, ofl,
1808 MSG_STR_COMMAND) == (Sym_desc *)S_ERROR)
1809 return (S_ERROR);
1810 break;
1811 case 'z':
1812 DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c,
1813 optarg));
1814 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32),
1815 MSG_ARG_LD32_SIZE) == 0) ||
1816 (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
1817 MSG_ARG_LD64_SIZE) == 0)) {
1818 if (createargv(ofl, 0) == S_ERROR)
1819 return (S_ERROR);
1820 } else if (strcmp(optarg,
1821 MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) {
1822 ofl->ofl_flags1 |= FLG_OF1_ALLEXRT;
1823 ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT;
1824 } else if (strcmp(optarg,
1825 MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) {
1826 ofl->ofl_flags1 |= FLG_OF1_WEAKEXT;
1827 ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT;
1828 } else if (strcmp(optarg,
1829 MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) {
1830 ofl->ofl_flags1 &=
1831 ~(FLG_OF1_ALLEXRT |
1832 FLG_OF1_WEAKEXT);
1833 } else if (strcmp(optarg,
1834 MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
1835 ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
1836 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1837 } else if (strcmp(optarg,
1838 MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
1839 ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
1840 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
1841 } else if (strcmp(optarg,
1842 MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
1843 ofl->ofl_flags1 |= FLG_OF1_IGNORE;
1844 } else if (strcmp(optarg,
1845 MSG_ORIG(MSG_ARG_RECORD)) == 0) {
1846 ofl->ofl_flags1 &= ~FLG_OF1_IGNORE;
1847 } else if (strcmp(optarg,
1848 MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
1849 ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
1850 ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1851 } else if (strcmp(optarg,
1852 MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
1853 ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
1854 ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
1855 } else if (strcmp(optarg,
1856 MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
1857 ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
1858 } else if (strcmp(optarg,
1859 MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) {
1860 ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM;
1861 } else if (strncmp(optarg,
1862 MSG_ORIG(MSG_ARG_INITARRAY),
1863 MSG_ARG_INITARRAY_SIZE) == 0) {
1864 if (((sdp = ld_sym_add_u(optarg +
1865 MSG_ARG_INITARRAY_SIZE, ofl,
1866 MSG_STR_COMMAND)) ==
1867 (Sym_desc *)S_ERROR) ||
1868 (aplist_append(&ofl->ofl_initarray,
1869 sdp, AL_CNT_OFL_ARRAYS) == NULL))
1870 return (S_ERROR);
1871 } else if (strncmp(optarg,
1872 MSG_ORIG(MSG_ARG_FINIARRAY),
1873 MSG_ARG_FINIARRAY_SIZE) == 0) {
1874 if (((sdp = ld_sym_add_u(optarg +
1875 MSG_ARG_FINIARRAY_SIZE, ofl,
1876 MSG_STR_COMMAND)) ==
1877 (Sym_desc *)S_ERROR) ||
1878 (aplist_append(&ofl->ofl_finiarray,
1879 sdp, AL_CNT_OFL_ARRAYS) == NULL))
1880 return (S_ERROR);
1881 } else if (strncmp(optarg,
1882 MSG_ORIG(MSG_ARG_PREINITARRAY),
1883 MSG_ARG_PREINITARRAY_SIZE) == 0) {
1884 if (((sdp = ld_sym_add_u(optarg +
1885 MSG_ARG_PREINITARRAY_SIZE, ofl,
1886 MSG_STR_COMMAND)) ==
1887 (Sym_desc *)S_ERROR) ||
1888 (aplist_append(&ofl->ofl_preiarray,
1889 sdp, AL_CNT_OFL_ARRAYS) == NULL))
1890 return (S_ERROR);
1891 } else if (strncmp(optarg,
1892 MSG_ORIG(MSG_ARG_RTLDINFO),
1893 MSG_ARG_RTLDINFO_SIZE) == 0) {
1894 if (((sdp = ld_sym_add_u(optarg +
1895 MSG_ARG_RTLDINFO_SIZE, ofl,
1896 MSG_STR_COMMAND)) ==
1897 (Sym_desc *)S_ERROR) ||
1898 (aplist_append(&ofl->ofl_rtldinfo,
1899 sdp, AL_CNT_OFL_ARRAYS) == NULL))
1900 return (S_ERROR);
1901 } else if (strncmp(optarg,
1902 MSG_ORIG(MSG_ARG_DTRACE),
1903 MSG_ARG_DTRACE_SIZE) == 0) {
1904 if ((sdp = ld_sym_add_u(optarg +
1905 MSG_ARG_DTRACE_SIZE, ofl,
1906 MSG_STR_COMMAND)) ==
1907 (Sym_desc *)S_ERROR)
1908 return (S_ERROR);
1909 ofl->ofl_dtracesym = sdp;
1910 } else if (strcmp(optarg,
1911 MSG_ORIG(MSG_ARG_RESCAN_NOW)) == 0) {
1912 if (ld_rescan_archives(ofl, 0, ndx) ==
1913 S_ERROR)
1914 return (S_ERROR);
1915 } else if (strcmp(optarg,
1916 MSG_ORIG(MSG_ARG_RESCAN_START)) == 0) {
1917 ofl->ofl_ars_gsndx = ofl->ofl_arscnt;
1918 ofl->ofl_ars_gsandx = ndx;
1919 } else if (strcmp(optarg,
1920 MSG_ORIG(MSG_ARG_RESCAN_END)) == 0) {
1921 if (ld_rescan_archives(ofl, 1, ndx) ==
1922 S_ERROR)
1923 return (S_ERROR);
1924 } else if (strcmp(optarg,
1925 MSG_ORIG(MSG_ARG_DEFERRED)) == 0) {
1926 ofl->ofl_flags1 |= FLG_OF1_DEFERRED;
1927 } else if (strcmp(optarg,
1928 MSG_ORIG(MSG_ARG_NODEFERRED)) == 0) {
1929 ofl->ofl_flags1 &= ~FLG_OF1_DEFERRED;
1931 default:
1932 break;
1936 * Update the argument index for the next getopt() iteration.
1938 ndx = optind;
1940 return (1);
1945 * Pass 1 -- process_flags: collects all options and sets flags
1947 static uintptr_t
1948 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
1950 for (; optind < argc; optind++) {
1952 * If we detect some more options return to getopt().
1953 * Checking argv[optind][1] against null prevents a forever
1954 * loop if an unadorned `-' argument is passed to us.
1956 while ((optind < argc) && (argv[optind][0] == '-')) {
1957 if (argv[optind][1] != '\0') {
1958 if (parseopt_pass1(ofl, argc, argv,
1959 usage) == S_ERROR)
1960 return (S_ERROR);
1961 } else if (++optind < argc)
1962 continue;
1964 if (optind >= argc)
1965 break;
1966 ofl->ofl_objscnt++;
1969 /* Did an unterminated archive group run off the end? */
1970 if (ofl->ofl_ars_gsandx > 0) {
1971 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
1972 MSG_INTL(MSG_MARG_AR_GRP_START),
1973 MSG_INTL(MSG_MARG_AR_GRP_END));
1974 return (S_ERROR);
1977 return (1);
1980 uintptr_t
1981 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
1983 int usage = 0; /* Collect all argument errors before exit */
1985 if (argc < 2) {
1986 usage_mesg(FALSE);
1987 return (S_ERROR);
1991 * Option handling
1993 opterr = 0;
1994 optind = 1;
1995 if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
1996 return (S_ERROR);
1999 * Having parsed everything, did we have any usage errors.
2001 if (usage) {
2002 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
2003 return (S_ERROR);
2006 return (check_flags(ofl, argc));
2010 * Pass 2 -- process_files: skips the flags collected in pass 1 and processes
2011 * files.
2013 static uintptr_t
2014 process_files_com(Ofl_desc *ofl, int argc, char **argv)
2016 for (; optind < argc; optind++) {
2017 int fd;
2018 uintptr_t open_ret;
2019 char *path;
2020 Rej_desc rej = { 0 };
2023 * If we detect some more options return to getopt().
2024 * Checking argv[optind][1] against null prevents a forever
2025 * loop if an unadorned `-' argument is passed to us.
2027 while ((optind < argc) && (argv[optind][0] == '-')) {
2028 if (argv[optind][1] != '\0') {
2029 if (parseopt_pass2(ofl, argc, argv) == S_ERROR)
2030 return (S_ERROR);
2031 } else if (++optind < argc)
2032 continue;
2034 if (optind >= argc)
2035 break;
2037 path = argv[optind];
2038 if ((fd = open(path, O_RDONLY)) == -1) {
2039 int err = errno;
2041 ld_eprintf(ofl, ERR_FATAL,
2042 MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
2043 continue;
2046 DBG_CALL(Dbg_args_file(ofl->ofl_lml, optind, path));
2048 open_ret = ld_process_open(path, path, &fd, ofl,
2049 (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej, NULL);
2050 if (fd != -1)
2051 (void) close(fd);
2052 if (open_ret == S_ERROR)
2053 return (S_ERROR);
2056 * Check for mismatched input.
2058 if (rej.rej_type) {
2059 Conv_reject_desc_buf_t rej_buf;
2061 ld_eprintf(ofl, ERR_FATAL,
2062 MSG_INTL(reject[rej.rej_type]),
2063 rej.rej_name ? rej.rej_name :
2064 MSG_INTL(MSG_STR_UNKNOWN),
2065 conv_reject_desc(&rej, &rej_buf,
2066 ld_targ.t_m.m_mach));
2067 return (1);
2070 return (1);
2073 uintptr_t
2074 ld_process_files(Ofl_desc *ofl, int argc, char **argv)
2076 DBG_CALL(Dbg_basic_files(ofl->ofl_lml));
2079 * Process command line files (taking into account any applicable
2080 * preceding flags). Return if any fatal errors have occurred.
2082 opterr = 0;
2083 optind = 1;
2084 if (process_files_com(ofl, argc, argv) == S_ERROR)
2085 return (S_ERROR);
2086 if (ofl->ofl_flags & FLG_OF_FATAL)
2087 return (1);
2090 * Guidance: Use -B direct/nodirect or -z direct/nodirect.
2092 * This is a backstop for the case where the link had no dependencies.
2093 * Otherwise, it will get caught by ld_process_ifl(). We need both,
2094 * because -z direct is positional, and its value at the time where
2095 * the first dependency is seen might be different than it is now.
2097 if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
2098 OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
2099 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
2100 ofl->ofl_guideflags |= FLG_OFG_NO_DB;
2104 * Now that all command line files have been processed see if there are
2105 * any additional `needed' shared object dependencies.
2107 if (ofl->ofl_soneed)
2108 if (ld_finish_libs(ofl) == S_ERROR)
2109 return (S_ERROR);
2112 * If rescanning archives is enabled, do so now to determine whether
2113 * there might still be members extracted to satisfy references from any
2114 * explicit objects. Continue until no new objects are extracted. Note
2115 * that this pass is carried out *after* processing any implicit objects
2116 * (above) as they may already have resolved any undefined references
2117 * from any explicit dependencies.
2119 if (ofl->ofl_flags1 & FLG_OF1_RESCAN) {
2120 if (ld_rescan_archives(ofl, 0, argc) == S_ERROR)
2121 return (S_ERROR);
2122 if (ofl->ofl_flags & FLG_OF_FATAL)
2123 return (1);
2127 * If debugging, provide statistics on each archives extraction, or flag
2128 * any archive that has provided no members. Note that this could be a
2129 * nice place to free up much of the archive infrastructure, as we've
2130 * extracted any members we need. However, as we presently don't free
2131 * anything under ld(1) there's not much point in proceeding further.
2133 DBG_CALL(Dbg_statistics_ar(ofl));
2136 * If any version definitions have been established, either via input
2137 * from a mapfile or from the input relocatable objects, make sure any
2138 * version dependencies are satisfied, and version symbols created.
2140 if (ofl->ofl_verdesc)
2141 if (ld_vers_check_defs(ofl) == S_ERROR)
2142 return (S_ERROR);
2145 * If input section ordering was specified within some segment
2146 * using a mapfile, verify that the expected sections were seen.
2148 if (ofl->ofl_flags & FLG_OF_IS_ORDER)
2149 ld_ent_check(ofl);
2151 return (1);
2154 uintptr_t
2155 ld_init_strings(Ofl_desc *ofl)
2157 uint_t stflags;
2159 if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB)
2160 stflags = 0;
2161 else
2162 stflags = FLG_STNEW_COMPRESS;
2164 if (((ofl->ofl_shdrsttab = st_new(stflags)) == NULL) ||
2165 ((ofl->ofl_strtab = st_new(stflags)) == NULL) ||
2166 ((ofl->ofl_dynstrtab = st_new(stflags)) == NULL))
2167 return (S_ERROR);
2169 return (0);