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