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