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