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