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