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