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