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