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