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