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