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