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