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