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