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