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 2008 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_ZTARG)); 191 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZT)); 192 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTO)); 193 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZTW)); 194 (void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZV)); 195 } 196 197 /* 198 * Checks the command line option flags for consistency. 199 */ 200 static uintptr_t 201 check_flags(Ofl_desc * ofl, int argc) 202 { 203 if (Plibpath && (Llibdir || Ulibdir)) { 204 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_YP), 205 Llibdir ? 'L' : 'U'); 206 ofl->ofl_flags |= FLG_OF_FATAL; 207 } 208 209 if (rflag) { 210 if (dflag == SET_UNKNOWN) 211 dflag = SET_FALSE; 212 if (ofl->ofl_flags & FLG_OF_COMREL) { 213 /* 214 * Combining relocations when building a relocatable 215 * object isn't allowed. Warn the user, but proceed. 216 */ 217 eprintf(ofl->ofl_lml, ERR_WARNING, 218 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_R), 219 MSG_ORIG(MSG_ARG_ZCOMBRELOC)); 220 ofl->ofl_flags &= ~FLG_OF_COMREL; 221 } 222 ofl->ofl_flags |= FLG_OF_RELOBJ; 223 } else { 224 /* 225 * If the user hasn't explicitly requested that relocations 226 * not be combined, combine them by default. 227 */ 228 if ((ofl->ofl_flags & FLG_OF_NOCOMREL) == 0) 229 ofl->ofl_flags |= FLG_OF_COMREL; 230 } 231 232 if (zdflag == SET_TRUE) 233 ofl->ofl_flags |= FLG_OF_NOUNDEF; 234 235 if (zinflag) 236 ofl->ofl_dtflags_1 |= DF_1_INTERPOSE; 237 238 if (sflag) 239 ofl->ofl_flags |= FLG_OF_STRIP; 240 241 if (Qflag == SET_TRUE) 242 ofl->ofl_flags |= FLG_OF_ADDVERS; 243 244 if (Blflag) 245 ofl->ofl_flags |= FLG_OF_AUTOLCL; 246 247 if (Beflag) 248 ofl->ofl_flags |= FLG_OF_AUTOELM; 249 250 if (Blflag && Beflag) { 251 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP), 252 MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL)); 253 ofl->ofl_flags |= FLG_OF_FATAL; 254 } 255 256 if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP)) { 257 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP), 258 MSG_ORIG(MSG_ARG_CI), MSG_ORIG(MSG_ARG_ZNOINTERP)); 259 ofl->ofl_flags |= FLG_OF_FATAL; 260 } 261 262 if ((ofl->ofl_flags1 & (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) == 263 (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) { 264 eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP), 265 MSG_ORIG(MSG_ARG_ZRELAXRELOC), 266 MSG_ORIG(MSG_ARG_ZNORELAXRELOC)); 267 ofl->ofl_flags |= FLG_OF_FATAL; 268 } 269 270 if (dflag != SET_FALSE) { 271 /* 272 * Set -Bdynamic on by default, setting is rechecked as input 273 * files are processed. 274 */ 275 ofl->ofl_flags |= 276 (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED); 277 278 if (aflag) { 279 eprintf(ofl->ofl_lml, ERR_FATAL, 280 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DY), 281 MSG_ORIG(MSG_ARG_A)); 282 ofl->ofl_flags |= FLG_OF_FATAL; 283 } 284 285 if (bflag) 286 ofl->ofl_flags |= FLG_OF_BFLAG; 287 288 if (Bgflag == TRUE) { 289 if (zdflag == SET_FALSE) { 290 eprintf(ofl->ofl_lml, ERR_FATAL, 291 MSG_INTL(MSG_ARG_INCOMP), 292 MSG_ORIG(MSG_ARG_BGROUP), 293 MSG_ORIG(MSG_ARG_ZNODEF)); 294 ofl->ofl_flags |= FLG_OF_FATAL; 295 } 296 ofl->ofl_dtflags_1 |= DF_1_GROUP; 297 ofl->ofl_flags |= FLG_OF_NOUNDEF; 298 } 299 300 /* 301 * If the use of default library searching has been suppressed 302 * but no runpaths have been provided we're going to have a hard 303 * job running this object. 304 */ 305 if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath) 306 eprintf(ofl->ofl_lml, ERR_WARNING, 307 MSG_INTL(MSG_ARG_NODEFLIB)); 308 309 /* 310 * By default, text relocation warnings are given when building 311 * an executable unless the -b flag is specified. This option 312 * implies that unclean text can be created, so no warnings are 313 * generated unless specifically asked for. 314 */ 315 if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) || 316 ((ztflag == 0) && bflag)) 317 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF; 318 else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) 319 ofl->ofl_flags |= FLG_OF_PURETXT; 320 321 if (Gflag || !rflag) { 322 /* 323 * Create a dynamic object. -Bdirect indicates that all 324 * references should be bound directly. This also 325 * enables lazyloading. Individual symbols can be 326 * bound directly (or not) using mapfiles and the 327 * DIRECT (NODIRECT) qualifier. With this capability, 328 * each syminfo entry is tagged SYMINFO_FLG_DIRECTBIND. 329 * Prior to this per-symbol direct binding, runtime 330 * direct binding was controlled via the DF_1_DIRECT 331 * flag. This flag affected all references from the 332 * object. -Bdirect continues to set this flag, and 333 * thus provides a means of taking a newly built 334 * direct binding object back to older systems. 335 * 336 * NOTE, any use of per-symbol NODIRECT bindings, or 337 * -znodirect, will disable the creation of the 338 * DF_1_DIRECT flag. Older runtime linkers do not 339 * have the capability to do per-symbol direct bindings. 340 */ 341 if (Bdflag == SET_TRUE) { 342 ofl->ofl_dtflags_1 |= DF_1_DIRECT; 343 ofl->ofl_flags1 |= FLG_OF1_LAZYLD; 344 ofl->ofl_flags |= FLG_OF_SYMINFO; 345 } 346 347 /* 348 * -Bnodirect disables directly binding to any symbols 349 * exported from the object being created. Individual 350 * references to external objects can still be affected 351 * by -zdirect or mapfile DIRECT directives. 352 */ 353 if (Bdflag == SET_FALSE) { 354 ofl->ofl_flags1 |= 355 (FLG_OF1_NDIRECT | FLG_OF1_ALNODIR); 356 ofl->ofl_flags |= FLG_OF_SYMINFO; 357 } 358 } 359 360 if (!Gflag && !rflag) { 361 /* 362 * Dynamically linked executable. 363 */ 364 ofl->ofl_flags |= FLG_OF_EXEC; 365 366 if (zdflag != SET_FALSE) 367 ofl->ofl_flags |= FLG_OF_NOUNDEF; 368 369 if (Bsflag) { 370 eprintf(ofl->ofl_lml, ERR_FATAL, 371 MSG_INTL(MSG_ARG_DYNINCOMP), 372 MSG_ORIG(MSG_ARG_BSYMBOLIC)); 373 ofl->ofl_flags |= FLG_OF_FATAL; 374 } 375 if (ofl->ofl_soname) { 376 eprintf(ofl->ofl_lml, ERR_FATAL, 377 MSG_INTL(MSG_ARG_DYNINCOMP), 378 MSG_ORIG(MSG_ARG_H)); 379 ofl->ofl_flags |= FLG_OF_FATAL; 380 } 381 if (Btflag) { 382 eprintf(ofl->ofl_lml, ERR_FATAL, 383 MSG_INTL(MSG_ARG_DYNINCOMP), 384 MSG_ORIG(MSG_ARG_BTRANS)); 385 ofl->ofl_flags |= FLG_OF_FATAL; 386 } 387 if (ofl->ofl_filtees) { 388 if (ofl->ofl_flags & FLG_OF_AUX) { 389 eprintf(ofl->ofl_lml, ERR_FATAL, 390 MSG_INTL(MSG_ARG_DYNINCOMP), 391 MSG_ORIG(MSG_ARG_F)); 392 } else { 393 eprintf(ofl->ofl_lml, ERR_FATAL, 394 MSG_INTL(MSG_ARG_DYNINCOMP), 395 MSG_ORIG(MSG_ARG_CF)); 396 } 397 ofl->ofl_flags |= FLG_OF_FATAL; 398 } 399 400 } else if (!rflag) { 401 /* 402 * Shared library. 403 */ 404 ofl->ofl_flags |= FLG_OF_SHAROBJ; 405 406 /* 407 * By default, print text relocation errors for 408 * executables but *not* for shared objects. 409 */ 410 if (ztflag == 0) 411 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF; 412 413 if (Bsflag) { 414 /* 415 * -Bsymbolic, and -Bnodirect make no sense. 416 */ 417 if (Bdflag == SET_FALSE) { 418 eprintf(ofl->ofl_lml, ERR_FATAL, 419 MSG_INTL(MSG_ARG_INCOMP), 420 MSG_ORIG(MSG_ARG_BSYMBOLIC), 421 MSG_ORIG(MSG_ARG_BNODIRECT)); 422 ofl->ofl_flags |= FLG_OF_FATAL; 423 } 424 ofl->ofl_flags |= FLG_OF_SYMBOLIC; 425 ofl->ofl_dtflags |= DF_SYMBOLIC; 426 } 427 428 if (Btflag) { 429 ofl->ofl_dtflags_1 |= 430 (DF_1_TRANS | DF_1_DIRECT); 431 ofl->ofl_flags |= FLG_OF_SYMINFO; 432 } 433 434 } else { 435 /* 436 * Dynamic relocatable object. 437 */ 438 if (ztflag == 0) 439 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF; 440 441 if (ofl->ofl_interp) { 442 eprintf(ofl->ofl_lml, ERR_FATAL, 443 MSG_INTL(MSG_ARG_INCOMP), 444 MSG_ORIG(MSG_ARG_R), MSG_ORIG(MSG_ARG_CI)); 445 ofl->ofl_flags |= FLG_OF_FATAL; 446 } 447 } 448 } else { 449 ofl->ofl_flags |= FLG_OF_STATIC; 450 451 if (bflag) { 452 eprintf(ofl->ofl_lml, ERR_FATAL, 453 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 454 MSG_ORIG(MSG_ARG_B)); 455 ofl->ofl_flags |= FLG_OF_FATAL; 456 } 457 if (ofl->ofl_soname) { 458 eprintf(ofl->ofl_lml, ERR_FATAL, 459 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 460 MSG_ORIG(MSG_ARG_H)); 461 ofl->ofl_flags |= FLG_OF_FATAL; 462 } 463 if (ofl->ofl_depaudit) { 464 eprintf(ofl->ofl_lml, ERR_FATAL, 465 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 466 MSG_ORIG(MSG_ARG_P)); 467 ofl->ofl_flags |= FLG_OF_FATAL; 468 } 469 if (ofl->ofl_audit) { 470 eprintf(ofl->ofl_lml, ERR_FATAL, 471 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 472 MSG_ORIG(MSG_ARG_CP)); 473 ofl->ofl_flags |= FLG_OF_FATAL; 474 } 475 if (ofl->ofl_config) { 476 eprintf(ofl->ofl_lml, ERR_FATAL, 477 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 478 MSG_ORIG(MSG_ARG_C)); 479 ofl->ofl_flags |= FLG_OF_FATAL; 480 } 481 if (ofl->ofl_filtees) { 482 if (ofl->ofl_flags & FLG_OF_AUX) { 483 eprintf(ofl->ofl_lml, ERR_FATAL, 484 MSG_INTL(MSG_ARG_INCOMP), 485 MSG_ORIG(MSG_ARG_DN), MSG_ORIG(MSG_ARG_F)); 486 } else { 487 eprintf(ofl->ofl_lml, ERR_FATAL, 488 MSG_INTL(MSG_ARG_INCOMP), 489 MSG_ORIG(MSG_ARG_DN), MSG_ORIG(MSG_ARG_CF)); 490 } 491 ofl->ofl_flags |= FLG_OF_FATAL; 492 } 493 if (ztflag) { 494 eprintf(ofl->ofl_lml, ERR_FATAL, 495 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 496 MSG_ORIG(MSG_ARG_ZTEXTALL)); 497 ofl->ofl_flags |= FLG_OF_FATAL; 498 } 499 if (Gflag) { 500 eprintf(ofl->ofl_lml, ERR_FATAL, 501 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DN), 502 MSG_ORIG(MSG_ARG_CG)); 503 ofl->ofl_flags |= FLG_OF_FATAL; 504 } 505 if (aflag && rflag) { 506 eprintf(ofl->ofl_lml, ERR_FATAL, 507 MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_A), 508 MSG_ORIG(MSG_ARG_R)); 509 ofl->ofl_flags |= FLG_OF_FATAL; 510 } 511 512 if (rflag) { 513 /* 514 * We can only strip the symbol table and string table 515 * if no output relocations will refer to them. 516 */ 517 if (sflag) { 518 eprintf(ofl->ofl_lml, ERR_WARNING, 519 MSG_INTL(MSG_ARG_STRIP)); 520 } 521 522 if (ztflag == 0) 523 ofl->ofl_flags1 |= FLG_OF1_TEXTOFF; 524 525 if (ofl->ofl_interp) { 526 eprintf(ofl->ofl_lml, ERR_FATAL, 527 MSG_INTL(MSG_ARG_INCOMP), 528 MSG_ORIG(MSG_ARG_R), MSG_ORIG(MSG_ARG_CI)); 529 ofl->ofl_flags |= FLG_OF_FATAL; 530 } 531 } else { 532 /* 533 * Static executable. 534 */ 535 ofl->ofl_flags |= FLG_OF_EXEC | FLG_OF_PROCRED; 536 537 if (zdflag != SET_FALSE) 538 ofl->ofl_flags |= FLG_OF_NOUNDEF; 539 } 540 } 541 542 /* 543 * If the user didn't supply an output file name supply a default. 544 */ 545 if (ofl->ofl_name == NULL) 546 ofl->ofl_name = MSG_ORIG(MSG_STR_AOUT); 547 548 /* 549 * We set the entrance criteria after all input argument processing as 550 * it is only at this point we're sure what the output image will be 551 * (static or dynamic). 552 */ 553 if (ld_ent_setup(ofl, ld_targ.t_m.m_segm_align) == S_ERROR) 554 return (S_ERROR); 555 556 /* 557 * Does the host currently running the linker have the same 558 * byte order as the target for which the object is being produced? 559 * If not, set FLG_OF1_ENCDIFF so relocation code will know 560 * to check. 561 */ 562 if (_elf_sys_encoding() != ld_targ.t_m.m_data) 563 ofl->ofl_flags1 |= FLG_OF1_ENCDIFF; 564 565 /* 566 * Initialize string tables. Symbol definitions within mapfiles can 567 * result in the creation of input sections. 568 */ 569 if (ld_init_strings(ofl) == S_ERROR) 570 return (S_ERROR); 571 572 /* 573 * Process any mapfiles after establishing the entrance criteria as 574 * the user may be redefining or adding sections/segments. 575 */ 576 if (ofl->ofl_maps.head) { 577 Listnode *lnp; 578 const char *name; 579 580 for (LIST_TRAVERSE(&ofl->ofl_maps, lnp, name)) 581 if (ld_map_parse(name, ofl) == S_ERROR) 582 return (S_ERROR); 583 584 if (ofl->ofl_flags & FLG_OF_SEGSORT) 585 if (ld_sort_seg_list(ofl) == S_ERROR) 586 return (S_ERROR); 587 } 588 589 /* 590 * If a mapfile has been used to define a single symbolic scope of 591 * interfaces, -Bsymbolic is established. This global setting goes 592 * beyond individual symbol protection, and ensures all relocations 593 * (even those that reference section symbols) are processed within 594 * the object being built. 595 */ 596 if (((ofl->ofl_flags & 597 (FLG_OF_MAPSYMB | FLG_OF_MAPGLOB)) == FLG_OF_MAPSYMB) && 598 (ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM))) { 599 ofl->ofl_flags |= FLG_OF_SYMBOLIC; 600 ofl->ofl_dtflags |= DF_SYMBOLIC; 601 } 602 603 /* 604 * If -zloadfltr is set, verify that filtering is in effect. Filters 605 * are either established from the command line, and affect the whole 606 * object, or are set on a per-symbol basis from a mapfile. 607 */ 608 if (zlflag) { 609 if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL)) { 610 eprintf(ofl->ofl_lml, ERR_FATAL, 611 MSG_INTL(MSG_ARG_NOFLTR), 612 MSG_ORIG(MSG_ARG_ZLOADFLTR)); 613 ofl->ofl_flags |= FLG_OF_FATAL; 614 } 615 ofl->ofl_dtflags_1 |= DF_1_LOADFLTR; 616 } 617 618 /* 619 * Check that we have something to work with. This check is carried out 620 * after mapfile processing as its possible a mapfile is being used to 621 * define symbols, in which case it would be sufficient to build the 622 * output file purely from the mapfile. 623 */ 624 if ((ofl->ofl_objscnt == 0) && (ofl->ofl_soscnt == 0)) { 625 if (Vflag && (argc == 2)) 626 ofl->ofl_flags1 |= FLG_OF1_DONE; 627 else { 628 eprintf(ofl->ofl_lml, ERR_FATAL, 629 MSG_INTL(MSG_ARG_NOFILES)); 630 return (S_ERROR); 631 } 632 } 633 return (1); 634 } 635 636 /* 637 * Decompose the string pointed by optarg into argv[][] so that argv[][] can be 638 * used as an argument to getopt(). 639 * 640 * If the second argument 'error' is not 0, then this is called from the first 641 * pass. Else this is called from the second pass. 642 */ 643 static uintptr_t 644 createargv(Ofl_desc *ofl, int *error) 645 { 646 int argc = 0, idx = 0, ooptind; 647 uintptr_t ret; 648 char **argv, *p0; 649 650 /* 651 * The argument being examined is either: 652 * ld32= or 653 * ld64= 654 */ 655 #if defined(_LP64) 656 if (optarg[2] == '3') 657 return (0); 658 #else 659 if (optarg[2] == '6') 660 return (0); 661 #endif 662 663 p0 = &optarg[5]; 664 665 /* 666 * Count the number of arguments. 667 */ 668 while (*p0) { 669 /* 670 * Pointing at non-separator character. 671 */ 672 if (*p0 != ',') { 673 argc++; 674 while (*p0 && (*p0 != ',')) 675 p0++; 676 continue; 677 } 678 679 /* 680 * Pointing at a separator character. 681 */ 682 if (*p0 == ',') { 683 while (*p0 == ',') 684 p0++; 685 continue; 686 } 687 } 688 689 if (argc == 0) 690 return (0); 691 692 /* 693 * Allocate argument vector. 694 */ 695 if ((p0 = (char *)strdup(&optarg[5])) == 0) 696 return (S_ERROR); 697 if ((argv = libld_malloc((sizeof (char *)) * (argc + 1))) == 0) 698 return (S_ERROR); 699 700 while (*p0) { 701 char *p; 702 703 /* 704 * Pointing at the beginning of non-separator character string. 705 */ 706 if (*p0 != ',') { 707 p = p0; 708 while (*p0 && (*p0 != ',')) 709 p0++; 710 argv[idx++] = p; 711 if (*p0) { 712 *p0 = '\0'; 713 p0++; 714 } 715 continue; 716 } 717 718 /* 719 * Pointing at the beginining of separator character string. 720 */ 721 if (*p0 == ',') { 722 while (*p0 == ',') 723 p0++; 724 continue; 725 } 726 } 727 argv[idx] = 0; 728 ooptind = optind; 729 optind = 0; 730 731 /* 732 * Dispatch to pass1 or pass2 733 */ 734 if (error) 735 ret = process_flags_com(ofl, argc, argv, error); 736 else 737 ret = process_files_com(ofl, argc, argv); 738 739 optind = ooptind; 740 741 if (ret == S_ERROR) 742 return (S_ERROR); 743 744 return (argc); 745 } 746 747 /* 748 * Parsing options pass1 for process_flags(). 749 */ 750 static uintptr_t 751 parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *error) 752 { 753 int c; 754 755 /* 756 * The -64 and -ztarget options are special, in that we validate 757 * them, but otherwise ignore them. libld.so (this code) is called 758 * from the ld front end program. ld has already examined the 759 * arguments to determine the output class and machine type of the 760 * output object, as reflected in the version (32/64) of ld_main() 761 * that was called and the value of the 'mach' argument passed. 762 * By time execution reaches this point, these options have already 763 * been seen and acted on. 764 */ 765 766 while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) { 767 DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c)); 768 769 switch (c) { 770 case '6': 771 /* 772 * -64 is processed by ld to determine the output class. 773 * Here we sanity check the option incase some other 774 * -6* option is mistakenly passed to us. 775 */ 776 if (optarg[0] != '4') { 777 eprintf(ofl->ofl_lml, ERR_FATAL, 778 MSG_INTL(MSG_ARG_ILLEGAL), 779 MSG_ORIG(MSG_ARG_6), optarg); 780 ofl->ofl_flags |= FLG_OF_FATAL; 781 } 782 continue; 783 784 case 'a': 785 aflag = TRUE; 786 break; 787 788 case 'b': 789 bflag = TRUE; 790 791 /* 792 * This is a hack, and may be undone later. 793 * The -b option is only used to build the Unix 794 * kernel and its related kernel-mode modules. 795 * We do not want those files to get a .SUNW_ldynsym 796 * section. At least for now, the kernel makes no 797 * use of .SUNW_ldynsym, and we do not want to use 798 * the space to hold it. Therefore, we overload 799 * the use of -b to also imply -znoldynsym. 800 */ 801 ofl->ofl_flags |= FLG_OF_NOLDYNSYM; 802 break; 803 804 case 'c': 805 if (ofl->ofl_config) 806 eprintf(ofl->ofl_lml, ERR_WARNING, 807 MSG_INTL(MSG_ARG_MTONCE), 808 MSG_ORIG(MSG_ARG_C)); 809 else 810 ofl->ofl_config = optarg; 811 break; 812 813 case 'C': 814 demangle_flag = 1; 815 break; 816 817 case 'd': 818 if ((optarg[0] == 'n') && (optarg[1] == '\0')) { 819 if (dflag != SET_UNKNOWN) 820 eprintf(ofl->ofl_lml, ERR_WARNING, 821 MSG_INTL(MSG_ARG_MTONCE), 822 MSG_ORIG(MSG_ARG_D)); 823 else 824 dflag = SET_FALSE; 825 } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) { 826 if (dflag != SET_UNKNOWN) 827 eprintf(ofl->ofl_lml, ERR_WARNING, 828 MSG_INTL(MSG_ARG_MTONCE), 829 MSG_ORIG(MSG_ARG_D)); 830 else 831 dflag = SET_TRUE; 832 } else { 833 eprintf(ofl->ofl_lml, ERR_FATAL, 834 MSG_INTL(MSG_ARG_ILLEGAL), 835 MSG_ORIG(MSG_ARG_D), optarg); 836 ofl->ofl_flags |= FLG_OF_FATAL; 837 } 838 break; 839 840 case 'e': 841 if (ofl->ofl_entry) 842 eprintf(ofl->ofl_lml, ERR_WARNING, 843 MSG_INTL(MSG_ARG_MTONCE), 844 MSG_ORIG(MSG_ARG_E)); 845 else 846 ofl->ofl_entry = (void *)optarg; 847 break; 848 849 case 'f': 850 if (ofl->ofl_filtees && 851 (!(ofl->ofl_flags & FLG_OF_AUX))) { 852 eprintf(ofl->ofl_lml, ERR_FATAL, 853 MSG_INTL(MSG_ARG_INCOMP), 854 MSG_ORIG(MSG_ARG_F), MSG_ORIG(MSG_ARG_CF)); 855 ofl->ofl_flags |= FLG_OF_FATAL; 856 } else { 857 if ((ofl->ofl_filtees = 858 add_string(ofl->ofl_filtees, optarg)) == 859 (const char *)S_ERROR) 860 return (S_ERROR); 861 ofl->ofl_flags |= FLG_OF_AUX; 862 } 863 break; 864 865 case 'F': 866 if (ofl->ofl_filtees && 867 (ofl->ofl_flags & FLG_OF_AUX)) { 868 eprintf(ofl->ofl_lml, ERR_FATAL, 869 MSG_INTL(MSG_ARG_INCOMP), 870 MSG_ORIG(MSG_ARG_CF), MSG_ORIG(MSG_ARG_F)); 871 ofl->ofl_flags |= FLG_OF_FATAL; 872 } else { 873 if ((ofl->ofl_filtees = 874 add_string(ofl->ofl_filtees, optarg)) == 875 (const char *)S_ERROR) 876 return (S_ERROR); 877 } 878 break; 879 880 case 'h': 881 if (ofl->ofl_soname) 882 eprintf(ofl->ofl_lml, ERR_WARNING, 883 MSG_INTL(MSG_ARG_MTONCE), 884 MSG_ORIG(MSG_ARG_H)); 885 else 886 ofl->ofl_soname = (const char *)optarg; 887 break; 888 889 case 'i': 890 ofl->ofl_flags |= FLG_OF_IGNENV; 891 break; 892 893 case 'I': 894 if (ofl->ofl_interp) 895 eprintf(ofl->ofl_lml, ERR_WARNING, 896 MSG_INTL(MSG_ARG_MTONCE), 897 MSG_ORIG(MSG_ARG_CI)); 898 else 899 ofl->ofl_interp = (const char *)optarg; 900 break; 901 902 case 'l': 903 /* 904 * For now, count any library as a shared object. This 905 * is used to size the internal symbol cache. This 906 * value is recalculated later on actual file processing 907 * to get an accurate shared object count. 908 */ 909 ofl->ofl_soscnt++; 910 break; 911 912 case 'm': 913 ofl->ofl_flags |= FLG_OF_GENMAP; 914 break; 915 916 case 'o': 917 if (ofl->ofl_name) 918 eprintf(ofl->ofl_lml, ERR_WARNING, 919 MSG_INTL(MSG_ARG_MTONCE), 920 MSG_ORIG(MSG_ARG_O)); 921 else 922 ofl->ofl_name = (const char *)optarg; 923 break; 924 925 case 'p': 926 /* 927 * Multiple instances of this option may occur. Each 928 * additional instance is effectively concatenated to 929 * the previous separated by a colon. 930 */ 931 if (*optarg != '\0') { 932 if ((ofl->ofl_audit = 933 add_string(ofl->ofl_audit, 934 optarg)) == (const char *)S_ERROR) 935 return (S_ERROR); 936 } 937 break; 938 939 case 'P': 940 /* 941 * Multiple instances of this option may occur. Each 942 * additional instance is effectively concatenated to 943 * the previous separated by a colon. 944 */ 945 if (*optarg != '\0') { 946 if ((ofl->ofl_depaudit = 947 add_string(ofl->ofl_depaudit, 948 optarg)) == (const char *)S_ERROR) 949 return (S_ERROR); 950 } 951 break; 952 953 case 'r': 954 rflag = TRUE; 955 break; 956 957 case 'R': 958 /* 959 * Multiple instances of this option may occur. Each 960 * additional instance is effectively concatenated to 961 * the previous separated by a colon. 962 */ 963 if (*optarg != '\0') { 964 if ((ofl->ofl_rpath = 965 add_string(ofl->ofl_rpath, 966 optarg)) == (const char *)S_ERROR) 967 return (S_ERROR); 968 } 969 break; 970 971 case 's': 972 sflag = TRUE; 973 break; 974 975 case 't': 976 ofl->ofl_flags |= FLG_OF_NOWARN; 977 break; 978 979 case 'u': 980 break; 981 982 case 'z': 983 /* 984 * For specific help, print our usage message and exit 985 * immediately to ensure a 0 return code. 986 */ 987 if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP), 988 MSG_ARG_HELP_SIZE) == 0) { 989 usage_mesg(1); 990 exit(0); 991 } 992 993 /* 994 * For some options set a flag - further consistancy 995 * checks will be carried out in check_flags(). 996 */ 997 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32), 998 MSG_ARG_LD32_SIZE) == 0) || 999 (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64), 1000 MSG_ARG_LD64_SIZE) == 0)) { 1001 if (createargv(ofl, error) == S_ERROR) 1002 return (S_ERROR); 1003 1004 } else if ( 1005 strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) { 1006 if (zdflag != SET_UNKNOWN) 1007 eprintf(ofl->ofl_lml, ERR_WARNING, 1008 MSG_INTL(MSG_ARG_MTONCE), 1009 MSG_ORIG(MSG_ARG_ZDEFNODEF)); 1010 else 1011 zdflag = SET_TRUE; 1012 } else if (strcmp(optarg, 1013 MSG_ORIG(MSG_ARG_NODEFS)) == 0) { 1014 if (zdflag != SET_UNKNOWN) 1015 eprintf(ofl->ofl_lml, ERR_WARNING, 1016 MSG_INTL(MSG_ARG_MTONCE), 1017 MSG_ORIG(MSG_ARG_ZDEFNODEF)); 1018 else 1019 zdflag = SET_FALSE; 1020 } else if (strcmp(optarg, 1021 MSG_ORIG(MSG_ARG_TEXT)) == 0) { 1022 if (ztflag && 1023 (ztflag != MSG_ORIG(MSG_ARG_ZTEXT))) { 1024 eprintf(ofl->ofl_lml, ERR_FATAL, 1025 MSG_INTL(MSG_ARG_INCOMP), 1026 MSG_ORIG(MSG_ARG_ZTEXT), 1027 ztflag); 1028 ofl->ofl_flags |= FLG_OF_FATAL; 1029 } 1030 ztflag = MSG_ORIG(MSG_ARG_ZTEXT); 1031 } else if (strcmp(optarg, 1032 MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) { 1033 if (ztflag && 1034 (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF))) { 1035 eprintf(ofl->ofl_lml, ERR_FATAL, 1036 MSG_INTL(MSG_ARG_INCOMP), 1037 MSG_ORIG(MSG_ARG_ZTEXTOFF), 1038 ztflag); 1039 ofl->ofl_flags |= FLG_OF_FATAL; 1040 } 1041 ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF); 1042 } else if (strcmp(optarg, 1043 MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) { 1044 if (ztflag && 1045 (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN))) { 1046 eprintf(ofl->ofl_lml, ERR_FATAL, 1047 MSG_INTL(MSG_ARG_INCOMP), 1048 MSG_ORIG(MSG_ARG_ZTEXTWARN), 1049 ztflag); 1050 ofl->ofl_flags |= FLG_OF_FATAL; 1051 } 1052 ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN); 1053 1054 /* 1055 * For other options simply set the ofl flags directly. 1056 */ 1057 } else if (strcmp(optarg, 1058 MSG_ORIG(MSG_ARG_RESCAN)) == 0) { 1059 ofl->ofl_flags1 |= FLG_OF1_RESCAN; 1060 } else if (strcmp(optarg, 1061 MSG_ORIG(MSG_ARG_ABSEXEC)) == 0) { 1062 ofl->ofl_flags1 |= FLG_OF1_ABSEXEC; 1063 } else if (strcmp(optarg, 1064 MSG_ORIG(MSG_ARG_LOADFLTR)) == 0) { 1065 zlflag = TRUE; 1066 } else if (strcmp(optarg, 1067 MSG_ORIG(MSG_ARG_NORELOC)) == 0) { 1068 ofl->ofl_dtflags_1 |= DF_1_NORELOC; 1069 } else if (strcmp(optarg, 1070 MSG_ORIG(MSG_ARG_NOVERSION)) == 0) { 1071 ofl->ofl_flags |= FLG_OF_NOVERSEC; 1072 } else if (strcmp(optarg, 1073 MSG_ORIG(MSG_ARG_MULDEFS)) == 0) { 1074 ofl->ofl_flags |= FLG_OF_MULDEFS; 1075 } else if (strcmp(optarg, 1076 MSG_ORIG(MSG_ARG_REDLOCSYM)) == 0) { 1077 ofl->ofl_flags |= FLG_OF_REDLSYM; 1078 } else if (strcmp(optarg, 1079 MSG_ORIG(MSG_ARG_INITFIRST)) == 0) { 1080 ofl->ofl_dtflags_1 |= DF_1_INITFIRST; 1081 } else if (strcmp(optarg, 1082 MSG_ORIG(MSG_ARG_NODELETE)) == 0) { 1083 ofl->ofl_dtflags_1 |= DF_1_NODELETE; 1084 } else if (strcmp(optarg, 1085 MSG_ORIG(MSG_ARG_NOPARTIAL)) == 0) { 1086 ofl->ofl_flags1 |= FLG_OF1_NOPARTI; 1087 } else if (strcmp(optarg, 1088 MSG_ORIG(MSG_ARG_NOOPEN)) == 0) { 1089 ofl->ofl_dtflags_1 |= DF_1_NOOPEN; 1090 } else if (strcmp(optarg, 1091 MSG_ORIG(MSG_ARG_NOW)) == 0) { 1092 ofl->ofl_dtflags_1 |= DF_1_NOW; 1093 ofl->ofl_dtflags |= DF_BIND_NOW; 1094 } else if (strcmp(optarg, 1095 MSG_ORIG(MSG_ARG_ORIGIN)) == 0) { 1096 ofl->ofl_dtflags_1 |= DF_1_ORIGIN; 1097 ofl->ofl_dtflags |= DF_ORIGIN; 1098 } else if (strcmp(optarg, 1099 MSG_ORIG(MSG_ARG_NODEFAULTLIB)) == 0) { 1100 ofl->ofl_dtflags_1 |= DF_1_NODEFLIB; 1101 } else if (strcmp(optarg, 1102 MSG_ORIG(MSG_ARG_NODUMP)) == 0) { 1103 ofl->ofl_dtflags_1 |= DF_1_NODUMP; 1104 } else if (strcmp(optarg, 1105 MSG_ORIG(MSG_ARG_ENDFILTEE)) == 0) { 1106 ofl->ofl_dtflags_1 |= DF_1_ENDFILTEE; 1107 } else if (strcmp(optarg, 1108 MSG_ORIG(MSG_ARG_VERBOSE)) == 0) { 1109 ofl->ofl_flags |= FLG_OF_VERBOSE; 1110 } else if (strcmp(optarg, 1111 MSG_ORIG(MSG_ARG_COMBRELOC)) == 0) { 1112 ofl->ofl_flags |= FLG_OF_COMREL; 1113 } else if (strcmp(optarg, 1114 MSG_ORIG(MSG_ARG_NOCOMBRELOC)) == 0) { 1115 ofl->ofl_flags |= FLG_OF_NOCOMREL; 1116 } else if (strcmp(optarg, 1117 MSG_ORIG(MSG_ARG_NOCOMPSTRTAB)) == 0) { 1118 ofl->ofl_flags1 |= FLG_OF1_NCSTTAB; 1119 } else if (strcmp(optarg, 1120 MSG_ORIG(MSG_ARG_NOINTERP)) == 0) { 1121 ofl->ofl_flags1 |= FLG_OF1_NOINTRP; 1122 } else if (strcmp(optarg, 1123 MSG_ORIG(MSG_ARG_INTERPOSE)) == 0) { 1124 zinflag = TRUE; 1125 } else if (strcmp(optarg, 1126 MSG_ORIG(MSG_ARG_IGNORE)) == 0) { 1127 ofl->ofl_flags1 |= FLG_OF1_IGNPRC; 1128 } else if (strcmp(optarg, 1129 MSG_ORIG(MSG_ARG_RELAXRELOC)) == 0) { 1130 ofl->ofl_flags1 |= FLG_OF1_RLXREL; 1131 } else if (strcmp(optarg, 1132 MSG_ORIG(MSG_ARG_NORELAXRELOC)) == 0) { 1133 ofl->ofl_flags1 |= FLG_OF1_NRLXREL; 1134 } else if (strcmp(optarg, 1135 MSG_ORIG(MSG_ARG_NOLDYNSYM)) == 0) { 1136 ofl->ofl_flags |= FLG_OF_NOLDYNSYM; 1137 } else if (strcmp(optarg, 1138 MSG_ORIG(MSG_ARG_GLOBAUDIT)) == 0) { 1139 ofl->ofl_dtflags_1 |= DF_1_GLOBAUDIT; 1140 /* 1141 * The following options just need validation as they 1142 * are interpreted on the second pass through the 1143 * command line arguments. 1144 */ 1145 } else if ( 1146 strncmp(optarg, MSG_ORIG(MSG_ARG_INITARRAY), 1147 MSG_ARG_INITARRAY_SIZE) && 1148 strncmp(optarg, MSG_ORIG(MSG_ARG_FINIARRAY), 1149 MSG_ARG_FINIARRAY_SIZE) && 1150 strncmp(optarg, MSG_ORIG(MSG_ARG_PREINITARRAY), 1151 MSG_ARG_PREINITARRAY_SIZE) && 1152 strncmp(optarg, MSG_ORIG(MSG_ARG_RTLDINFO), 1153 MSG_ARG_RTLDINFO_SIZE) && 1154 strncmp(optarg, MSG_ORIG(MSG_ARG_DTRACE), 1155 MSG_ARG_DTRACE_SIZE) && 1156 strcmp(optarg, MSG_ORIG(MSG_ARG_ALLEXTRT)) && 1157 strcmp(optarg, MSG_ORIG(MSG_ARG_DFLEXTRT)) && 1158 strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) && 1159 strcmp(optarg, MSG_ORIG(MSG_ARG_NODIRECT)) && 1160 strcmp(optarg, MSG_ORIG(MSG_ARG_GROUPPERM)) && 1161 strcmp(optarg, MSG_ORIG(MSG_ARG_LAZYLOAD)) && 1162 strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) && 1163 strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) && 1164 strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) && 1165 strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) && 1166 strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT)) && 1167 strncmp(optarg, MSG_ORIG(MSG_ARG_TARGET), 1168 MSG_ARG_TARGET_SIZE)) { 1169 eprintf(ofl->ofl_lml, ERR_FATAL, 1170 MSG_INTL(MSG_ARG_ILLEGAL), 1171 MSG_ORIG(MSG_ARG_Z), optarg); 1172 ofl->ofl_flags |= FLG_OF_FATAL; 1173 } 1174 1175 break; 1176 1177 case 'D': 1178 /* 1179 * If we have not yet read any input files go ahead 1180 * and process any debugging options (this allows any 1181 * argument processing, entrance criteria and library 1182 * initialization to be displayed). Otherwise, if an 1183 * input file has been seen, skip interpretation until 1184 * process_files (this allows debugging to be turned 1185 * on and off around individual groups of files). 1186 */ 1187 if (ofl->ofl_objscnt == 0) { 1188 if (dbg_setup(optarg, dbg_desc, 1189 &ofl->ofl_name, 1) == S_ERROR) 1190 return (S_ERROR); 1191 } 1192 break; 1193 1194 case 'B': 1195 if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) { 1196 if (Bdflag == SET_FALSE) { 1197 eprintf(ofl->ofl_lml, ERR_FATAL, 1198 MSG_INTL(MSG_ARG_INCOMP), 1199 MSG_ORIG(MSG_ARG_BNODIRECT), 1200 MSG_ORIG(MSG_ARG_BDIRECT)); 1201 ofl->ofl_flags |= FLG_OF_FATAL; 1202 } else 1203 Bdflag = SET_TRUE; 1204 } else if (strcmp(optarg, 1205 MSG_ORIG(MSG_ARG_NODIRECT)) == 0) { 1206 if (Bdflag == SET_TRUE) { 1207 eprintf(ofl->ofl_lml, ERR_FATAL, 1208 MSG_INTL(MSG_ARG_INCOMP), 1209 MSG_ORIG(MSG_ARG_BDIRECT), 1210 MSG_ORIG(MSG_ARG_BNODIRECT)); 1211 ofl->ofl_flags |= FLG_OF_FATAL; 1212 } else 1213 Bdflag = SET_FALSE; 1214 } else if (strcmp(optarg, 1215 MSG_ORIG(MSG_STR_SYMBOLIC)) == 0) 1216 Bsflag = TRUE; 1217 else if (strcmp(optarg, MSG_ORIG(MSG_ARG_REDUCE)) == 0) 1218 ofl->ofl_flags |= FLG_OF_PROCRED; 1219 else if (strcmp(optarg, MSG_ORIG(MSG_STR_LOCAL)) == 0) 1220 Blflag = TRUE; 1221 else if (strcmp(optarg, 1222 MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) 1223 Btflag = TRUE; 1224 else if (strcmp(optarg, MSG_ORIG(MSG_ARG_GROUP)) == 0) 1225 Bgflag = TRUE; 1226 else if (strcmp(optarg, 1227 MSG_ORIG(MSG_STR_ELIMINATE)) == 0) 1228 Beflag = TRUE; 1229 else if (strcmp(optarg, MSG_ORIG(MSG_STR_LD_DYNAMIC)) && 1230 strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) { 1231 eprintf(ofl->ofl_lml, ERR_FATAL, 1232 MSG_INTL(MSG_ARG_ILLEGAL), 1233 MSG_ORIG(MSG_ARG_CB), optarg); 1234 ofl->ofl_flags |= FLG_OF_FATAL; 1235 } 1236 break; 1237 1238 case 'G': 1239 Gflag = TRUE; 1240 break; 1241 1242 case 'L': 1243 break; 1244 1245 case 'M': 1246 if (list_appendc(&(ofl->ofl_maps), optarg) == 0) 1247 return (S_ERROR); 1248 break; 1249 1250 case 'N': 1251 break; 1252 1253 case 'Q': 1254 if ((optarg[0] == 'n') && (optarg[1] == '\0')) { 1255 if (Qflag != SET_UNKNOWN) 1256 eprintf(ofl->ofl_lml, ERR_WARNING, 1257 MSG_INTL(MSG_ARG_MTONCE), 1258 MSG_ORIG(MSG_ARG_CQ)); 1259 else 1260 Qflag = SET_FALSE; 1261 } else if ((optarg[0] == 'y') && (optarg[1] == '\0')) { 1262 if (Qflag != SET_UNKNOWN) 1263 eprintf(ofl->ofl_lml, ERR_WARNING, 1264 MSG_INTL(MSG_ARG_MTONCE), 1265 MSG_ORIG(MSG_ARG_CQ)); 1266 else 1267 Qflag = SET_TRUE; 1268 } else { 1269 eprintf(ofl->ofl_lml, ERR_FATAL, 1270 MSG_INTL(MSG_ARG_ILLEGAL), 1271 MSG_ORIG(MSG_ARG_CQ), optarg); 1272 ofl->ofl_flags |= FLG_OF_FATAL; 1273 } 1274 break; 1275 1276 case 'S': 1277 if (list_appendc(&lib_support, optarg) == 0) 1278 return (S_ERROR); 1279 break; 1280 1281 case 'V': 1282 if (!Vflag) 1283 (void) fprintf(stderr, MSG_ORIG(MSG_STR_STRNL), 1284 ofl->ofl_sgsid); 1285 Vflag = TRUE; 1286 break; 1287 1288 case 'Y': 1289 if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) { 1290 if (Llibdir) 1291 eprintf(ofl->ofl_lml, ERR_WARNING, 1292 MSG_INTL(MSG_ARG_MTONCE), 1293 MSG_ORIG(MSG_ARG_CYL)); 1294 else 1295 Llibdir = optarg + 2; 1296 } else if (strncmp(optarg, 1297 MSG_ORIG(MSG_ARG_UCOM), 2) == 0) { 1298 if (Ulibdir) 1299 eprintf(ofl->ofl_lml, ERR_WARNING, 1300 MSG_INTL(MSG_ARG_MTONCE), 1301 MSG_ORIG(MSG_ARG_CYU)); 1302 else 1303 Ulibdir = optarg + 2; 1304 } else if (strncmp(optarg, 1305 MSG_ORIG(MSG_ARG_PCOM), 2) == 0) { 1306 if (Plibpath) 1307 eprintf(ofl->ofl_lml, ERR_WARNING, 1308 MSG_INTL(MSG_ARG_MTONCE), 1309 MSG_ORIG(MSG_ARG_CYP)); 1310 else 1311 Plibpath = optarg + 2; 1312 } else { 1313 eprintf(ofl->ofl_lml, ERR_FATAL, 1314 MSG_INTL(MSG_ARG_ILLEGAL), 1315 MSG_ORIG(MSG_ARG_CY), optarg); 1316 ofl->ofl_flags |= FLG_OF_FATAL; 1317 } 1318 break; 1319 1320 case '?': 1321 (*error)++; 1322 break; 1323 1324 default: 1325 break; 1326 } 1327 } 1328 return (1); 1329 } 1330 1331 /* 1332 * Parsing options pass2 for 1333 */ 1334 static uintptr_t 1335 parseopt_pass2(Ofl_desc *ofl, int argc, char **argv) 1336 { 1337 int c; 1338 1339 while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) { 1340 Ifl_desc *ifl; 1341 Sym_desc *sdp; 1342 1343 DBG_CALL(Dbg_args_flags(ofl->ofl_lml, (optind - 1), c)); 1344 switch (c) { 1345 case 'l': 1346 if (ld_find_library(optarg, ofl) == S_ERROR) 1347 return (S_ERROR); 1348 break; 1349 case 'B': 1350 if (strcmp(optarg, 1351 MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) { 1352 if (ofl->ofl_flags & FLG_OF_DYNAMIC) 1353 ofl->ofl_flags |= 1354 FLG_OF_DYNLIBS; 1355 else { 1356 eprintf(ofl->ofl_lml, ERR_FATAL, 1357 MSG_INTL(MSG_ARG_INCOMP), 1358 MSG_ORIG(MSG_ARG_DN), 1359 MSG_ORIG(MSG_ARG_BDYNAMIC)); 1360 ofl->ofl_flags |= FLG_OF_FATAL; 1361 } 1362 } else if (strcmp(optarg, 1363 MSG_ORIG(MSG_ARG_STATIC)) == 0) 1364 ofl->ofl_flags &= ~FLG_OF_DYNLIBS; 1365 break; 1366 case 'L': 1367 if (ld_add_libdir(ofl, optarg) == S_ERROR) 1368 return (S_ERROR); 1369 break; 1370 case 'N': 1371 /* 1372 * Record DT_NEEDED string 1373 */ 1374 if (!(ofl->ofl_flags & FLG_OF_DYNAMIC)) { 1375 eprintf(ofl->ofl_lml, ERR_FATAL, 1376 MSG_INTL(MSG_ARG_INCOMP), 1377 MSG_ORIG(MSG_ARG_DN), 1378 MSG_ORIG(MSG_ARG_CN)); 1379 ofl->ofl_flags |= FLG_OF_FATAL; 1380 } 1381 if (((ifl = 1382 libld_calloc(1, sizeof (Ifl_desc))) == 0) || 1383 (list_appendc(&ofl->ofl_sos, ifl) == 0)) 1384 return (S_ERROR); 1385 1386 ifl->ifl_name = MSG_INTL(MSG_STR_COMMAND); 1387 ifl->ifl_soname = optarg; 1388 ifl->ifl_flags = (FLG_IF_NEEDSTR | 1389 FLG_IF_FILEREF | FLG_IF_DEPREQD); 1390 1391 break; 1392 case 'D': 1393 (void) dbg_setup(optarg, dbg_desc, 1394 &ofl->ofl_name, 2); 1395 break; 1396 case 'u': 1397 if (ld_sym_add_u(optarg, ofl, 1398 MSG_STR_COMMAND) == (Sym_desc *)S_ERROR) 1399 return (S_ERROR); 1400 break; 1401 case 'z': 1402 if ((strncmp(optarg, MSG_ORIG(MSG_ARG_LD32), 1403 MSG_ARG_LD32_SIZE) == 0) || 1404 (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64), 1405 MSG_ARG_LD64_SIZE) == 0)) { 1406 if (createargv(ofl, 0) == S_ERROR) 1407 return (S_ERROR); 1408 } else if (strcmp(optarg, 1409 MSG_ORIG(MSG_ARG_ALLEXTRT)) == 0) { 1410 ofl->ofl_flags1 |= FLG_OF1_ALLEXRT; 1411 ofl->ofl_flags1 &= ~FLG_OF1_WEAKEXT; 1412 } else if (strcmp(optarg, 1413 MSG_ORIG(MSG_ARG_WEAKEXT)) == 0) { 1414 ofl->ofl_flags1 |= FLG_OF1_WEAKEXT; 1415 ofl->ofl_flags1 &= ~FLG_OF1_ALLEXRT; 1416 } else if (strcmp(optarg, 1417 MSG_ORIG(MSG_ARG_DFLEXTRT)) == 0) { 1418 ofl->ofl_flags1 &= 1419 ~(FLG_OF1_ALLEXRT | 1420 FLG_OF1_WEAKEXT); 1421 } else if (strcmp(optarg, 1422 MSG_ORIG(MSG_ARG_DIRECT)) == 0) { 1423 ofl->ofl_flags1 |= FLG_OF1_ZDIRECT; 1424 } else if (strcmp(optarg, 1425 MSG_ORIG(MSG_ARG_NODIRECT)) == 0) { 1426 ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT; 1427 ofl->ofl_flags1 |= FLG_OF1_NDIRECT; 1428 } else if (strcmp(optarg, 1429 MSG_ORIG(MSG_ARG_IGNORE)) == 0) { 1430 ofl->ofl_flags1 |= FLG_OF1_IGNORE; 1431 } else if (strcmp(optarg, 1432 MSG_ORIG(MSG_ARG_RECORD)) == 0) { 1433 ofl->ofl_flags1 &= ~FLG_OF1_IGNORE; 1434 } else if (strcmp(optarg, 1435 MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) { 1436 ofl->ofl_flags1 |= FLG_OF1_LAZYLD; 1437 } else if (strcmp(optarg, 1438 MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) { 1439 ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD; 1440 } else if (strcmp(optarg, 1441 MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) { 1442 ofl->ofl_flags1 |= FLG_OF1_GRPPRM; 1443 } else if (strcmp(optarg, 1444 MSG_ORIG(MSG_ARG_NOGROUPPERM)) == 0) { 1445 ofl->ofl_flags1 &= ~FLG_OF1_GRPPRM; 1446 } else if (strncmp(optarg, 1447 MSG_ORIG(MSG_ARG_INITARRAY), 1448 MSG_ARG_INITARRAY_SIZE) == 0) { 1449 if (((sdp = ld_sym_add_u(optarg + 1450 MSG_ARG_INITARRAY_SIZE, ofl, 1451 MSG_STR_COMMAND)) == 1452 (Sym_desc *)S_ERROR) || 1453 (list_appendc(&ofl->ofl_initarray, 1454 sdp) == 0)) 1455 return (S_ERROR); 1456 } else if (strncmp(optarg, 1457 MSG_ORIG(MSG_ARG_FINIARRAY), 1458 MSG_ARG_FINIARRAY_SIZE) == 0) { 1459 if (((sdp = ld_sym_add_u(optarg + 1460 MSG_ARG_FINIARRAY_SIZE, ofl, 1461 MSG_STR_COMMAND)) == 1462 (Sym_desc *)S_ERROR) || 1463 (list_appendc(&ofl->ofl_finiarray, 1464 sdp) == 0)) 1465 return (S_ERROR); 1466 } else if (strncmp(optarg, 1467 MSG_ORIG(MSG_ARG_PREINITARRAY), 1468 MSG_ARG_PREINITARRAY_SIZE) == 0) { 1469 if (((sdp = ld_sym_add_u(optarg + 1470 MSG_ARG_PREINITARRAY_SIZE, ofl, 1471 MSG_STR_COMMAND)) == 1472 (Sym_desc *)S_ERROR) || 1473 (list_appendc(&ofl->ofl_preiarray, 1474 sdp) == 0)) 1475 return (S_ERROR); 1476 } else if (strncmp(optarg, 1477 MSG_ORIG(MSG_ARG_RTLDINFO), 1478 MSG_ARG_RTLDINFO_SIZE) == 0) { 1479 if (((sdp = ld_sym_add_u(optarg + 1480 MSG_ARG_RTLDINFO_SIZE, ofl, 1481 MSG_STR_COMMAND)) == 1482 (Sym_desc *)S_ERROR) || 1483 (list_appendc(&ofl->ofl_rtldinfo, 1484 sdp) == 0)) 1485 return (S_ERROR); 1486 } else if (strncmp(optarg, 1487 MSG_ORIG(MSG_ARG_DTRACE), 1488 MSG_ARG_DTRACE_SIZE) == 0) { 1489 if ((sdp = ld_sym_add_u(optarg + 1490 MSG_ARG_DTRACE_SIZE, ofl, 1491 MSG_STR_COMMAND)) == 1492 (Sym_desc *)S_ERROR) 1493 return (S_ERROR); 1494 ofl->ofl_dtracesym = sdp; 1495 } 1496 default: 1497 break; 1498 } 1499 } 1500 return (1); 1501 } 1502 1503 /* 1504 * 1505 * Pass 1 -- process_flags: collects all options and sets flags 1506 */ 1507 static uintptr_t 1508 process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *e) 1509 { 1510 for (; optind < argc; optind++) { 1511 /* 1512 * If we detect some more options return to getopt(). 1513 * Checking argv[optind][1] against null prevents a forever 1514 * loop if an unadorned `-' argument is passed to us. 1515 */ 1516 while ((optind < argc) && (argv[optind][0] == '-')) { 1517 if (argv[optind][1] != '\0') { 1518 if (parseopt_pass1(ofl, argc, argv, e) == 1519 S_ERROR) 1520 return (S_ERROR); 1521 } else if (++optind < argc) 1522 continue; 1523 } 1524 if (optind >= argc) 1525 break; 1526 ofl->ofl_objscnt++; 1527 } 1528 return (1); 1529 } 1530 1531 uintptr_t 1532 ld_process_flags(Ofl_desc *ofl, int argc, char **argv) 1533 { 1534 int error = 0; /* Collect all argument errors before exit */ 1535 1536 if (argc < 2) { 1537 usage_mesg(FALSE); 1538 return (S_ERROR); 1539 } 1540 1541 /* 1542 * Option handling 1543 */ 1544 if (process_flags_com(ofl, argc, argv, &error) == S_ERROR) 1545 return (S_ERROR); 1546 1547 /* 1548 * Having parsed everything, did we have any errors. 1549 */ 1550 if (error) { 1551 usage_mesg(TRUE); 1552 return (S_ERROR); 1553 } 1554 1555 return (check_flags(ofl, argc)); 1556 } 1557 1558 /* 1559 * Pass 2 -- process_files: skips the flags collected in pass 1 and processes 1560 * files. 1561 */ 1562 static uintptr_t 1563 process_files_com(Ofl_desc *ofl, int argc, char **argv) 1564 { 1565 for (; optind < argc; optind++) { 1566 int fd; 1567 Ifl_desc *ifl; 1568 char *path; 1569 Rej_desc rej = { 0 }; 1570 1571 /* 1572 * If we detect some more options return to getopt(). 1573 * Checking argv[optind][1] against null prevents a forever 1574 * loop if an unadorned `-' argument is passed to us. 1575 */ 1576 while ((optind < argc) && (argv[optind][0] == '-')) { 1577 if (argv[optind][1] != '\0') { 1578 if (parseopt_pass2(ofl, argc, argv) == S_ERROR) 1579 return (S_ERROR); 1580 } else if (++optind < argc) 1581 continue; 1582 } 1583 if (optind >= argc) 1584 break; 1585 1586 path = argv[optind]; 1587 if ((fd = open(path, O_RDONLY)) == -1) { 1588 int err = errno; 1589 1590 eprintf(ofl->ofl_lml, ERR_FATAL, 1591 MSG_INTL(MSG_SYS_OPEN), path, strerror(err)); 1592 ofl->ofl_flags |= FLG_OF_FATAL; 1593 continue; 1594 } 1595 1596 DBG_CALL(Dbg_args_files(ofl->ofl_lml, optind, path)); 1597 1598 ifl = ld_process_open(path, path, &fd, ofl, 1599 (FLG_IF_CMDLINE | FLG_IF_NEEDED), &rej); 1600 if (fd != -1) 1601 (void) close(fd); 1602 if (ifl == (Ifl_desc *)S_ERROR) 1603 return (S_ERROR); 1604 1605 /* 1606 * Check for mismatched input. 1607 */ 1608 if (rej.rej_type) { 1609 Conv_reject_desc_buf_t rej_buf; 1610 1611 eprintf(ofl->ofl_lml, ERR_FATAL, 1612 MSG_INTL(reject[rej.rej_type]), 1613 rej.rej_name ? rej.rej_name : 1614 MSG_INTL(MSG_STR_UNKNOWN), 1615 conv_reject_desc(&rej, &rej_buf, 1616 ld_targ.t_m.m_mach)); 1617 ofl->ofl_flags |= FLG_OF_FATAL; 1618 return (1); 1619 } 1620 } 1621 return (1); 1622 } 1623 1624 uintptr_t 1625 ld_process_files(Ofl_desc *ofl, int argc, char **argv) 1626 { 1627 optind = 1; /* reinitialize optind */ 1628 1629 /* 1630 * Process command line files (taking into account any applicable 1631 * preseeding flags). Return if any fatal errors have occurred. 1632 */ 1633 if (process_files_com(ofl, argc, argv) == S_ERROR) 1634 return (S_ERROR); 1635 if (ofl->ofl_flags & FLG_OF_FATAL) 1636 return (1); 1637 1638 /* 1639 * Now that all command line files have been processed see if there are 1640 * any additional `needed' shared object dependencies. 1641 */ 1642 if (ofl->ofl_soneed.head) 1643 if (ld_finish_libs(ofl) == S_ERROR) 1644 return (S_ERROR); 1645 1646 /* 1647 * If rescanning archives is enabled, do so now to determine whether 1648 * there might still be members extracted to satisfy references from any 1649 * explicit objects. Continue until no new objects are extracted. Note 1650 * that this pass is carried out *after* processing any implicit objects 1651 * (above) as they may already have resolved any undefined references 1652 * from any explicit dependencies. 1653 */ 1654 if (ofl->ofl_flags1 & FLG_OF1_RESCAN) 1655 ofl->ofl_flags1 |= FLG_OF1_EXTRACT; 1656 while ((ofl->ofl_flags1 & (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) == 1657 (FLG_OF1_RESCAN | FLG_OF1_EXTRACT)) { 1658 Listnode *lnp; 1659 Ar_desc *adp; 1660 1661 ofl->ofl_flags1 &= ~FLG_OF1_EXTRACT; 1662 1663 DBG_CALL(Dbg_file_ar_rescan(ofl->ofl_lml)); 1664 1665 for (LIST_TRAVERSE(&ofl->ofl_ars, lnp, adp)) { 1666 /* 1667 * If this archive was processed with -z allextract, 1668 * then all members have already been extracted. 1669 */ 1670 if (adp->ad_elf == NULL) 1671 continue; 1672 1673 /* 1674 * Reestablish any archive specific command line flags. 1675 */ 1676 ofl->ofl_flags1 &= ~MSK_OF1_ARCHIVE; 1677 ofl->ofl_flags1 |= (adp->ad_flags & MSK_OF1_ARCHIVE); 1678 1679 /* 1680 * Re-process the archive. Note that a file descriptor 1681 * is unnecessary, as the file is already available in 1682 * memory. 1683 */ 1684 if (ld_process_archive(adp->ad_name, -1, 1685 adp, ofl) == S_ERROR) 1686 return (S_ERROR); 1687 if (ofl->ofl_flags & FLG_OF_FATAL) 1688 return (1); 1689 } 1690 } 1691 1692 /* 1693 * If debugging, provide statistics on each archives extraction, or flag 1694 * any archive that has provided no members. Note that this could be a 1695 * nice place to free up much of the archive infrastructure, as we've 1696 * extracted any members we need. However, as we presently don't free 1697 * anything under ld(1) there's not much point in proceeding further. 1698 */ 1699 DBG_CALL(Dbg_statistics_ar(ofl)); 1700 1701 /* 1702 * If any version definitions have been established, either via input 1703 * from a mapfile or from the input relocatable objects, make sure any 1704 * version dependencies are satisfied, and version symbols created. 1705 */ 1706 if (ofl->ofl_verdesc.head) 1707 if (ld_vers_check_defs(ofl) == S_ERROR) 1708 return (S_ERROR); 1709 1710 /* 1711 * If segment ordering was specified (using mapfile) verify things 1712 * are ok. 1713 */ 1714 if (ofl->ofl_flags & FLG_OF_SEGORDER) 1715 ld_ent_check(ofl); 1716 1717 return (1); 1718 } 1719 1720 uintptr_t 1721 ld_init_strings(Ofl_desc *ofl) 1722 { 1723 uint_t stflags; 1724 1725 if (ofl->ofl_flags1 & FLG_OF1_NCSTTAB) 1726 stflags = 0; 1727 else 1728 stflags = FLG_STNEW_COMPRESS; 1729 1730 if (((ofl->ofl_shdrsttab = st_new(stflags)) == 0) || 1731 ((ofl->ofl_strtab = st_new(stflags)) == 0) || 1732 ((ofl->ofl_dynstrtab = st_new(stflags)) == 0)) 1733 return (S_ERROR); 1734 1735 return (0); 1736 } 1737