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