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