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