Print this page
10138 smatch fixes for usr/src/cmd/sgs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/libld/common/util.c
+++ new/usr/src/cmd/sgs/libld/common/util.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
22 22 /*
23 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Copyright (c) 1988 AT&T
28 28 * All Rights Reserved
29 29 */
30 30
31 31 /*
32 + * Copyright (c) 2018, Joyent, Inc.
33 + */
34 +
35 +/*
32 36 * Utility functions
33 37 */
34 38 #include <unistd.h>
35 39 #include <stdio.h>
36 40 #include <stdarg.h>
37 41 #include <string.h>
38 42 #include <fcntl.h>
39 43 #include <sys/types.h>
40 44 #include <sys/mman.h>
41 45 #include <errno.h>
42 46 #include <sgs.h>
43 47 #include <libintl.h>
44 48 #include <debug.h>
45 49 #include "msg.h"
46 50 #include "_libld.h"
47 51
48 52 /*
49 53 * libld_malloc() and dz_map() are used for both performance and for ease of
50 54 * programming:
51 55 *
52 56 * Performance:
53 57 * The link-edit is a short lived process which doesn't really free much
54 58 * of the dynamic memory that it requests. Because of this, it is more
55 59 * important to optimize for quick memory allocations than the
56 60 * re-usability of the memory.
57 61 *
58 62 * By also mmaping blocks of pages in from /dev/zero we don't need to
59 63 * waste the overhead of zeroing out these pages for calloc() requests.
60 64 *
61 65 * Memory Management:
62 66 * By doing all libld memory management through the ld_malloc routine
63 67 * it's much easier to free up all memory at the end by simply unmaping
64 68 * all of the blocks that were mapped in through dz_map(). This is much
65 69 * simpler then trying to track all of the libld structures that were
66 70 * dynamically allocate and are actually pointers into the ELF files.
67 71 *
68 72 * It's important that we can free up all of our dynamic memory because
69 73 * libld is used by ld.so.1 when it performs dlopen()'s of relocatable
70 74 * objects.
71 75 *
72 76 * Format:
73 77 * The memory blocks for each allocation store the size of the allocation
74 78 * in the first 8 bytes of the block. The pointer that is returned by
75 79 * libld_malloc() is actually the address of (block + 8):
76 80 *
77 81 * (addr - 8) block_size
78 82 * (addr) <allocated block>
79 83 *
80 84 * The size is retained in order to implement realloc(), and to perform
81 85 * the required memcpy(). 8 bytes are uses, as the memory area returned
82 86 * by libld_malloc() must be 8 byte-aligned. Even in a 32-bit environment,
83 87 * u_longlog_t pointers are employed.
84 88 *
85 89 * Map anonymous memory via MAP_ANON (added in Solaris 8).
86 90 */
87 91 static void *
88 92 dz_map(size_t size)
89 93 {
90 94 void *addr;
91 95
92 96 if ((addr = mmap(0, size, (PROT_READ | PROT_WRITE | PROT_EXEC),
93 97 (MAP_PRIVATE | MAP_ANON), -1, 0)) == MAP_FAILED) {
94 98 int err = errno;
95 99 eprintf(NULL, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON),
96 100 strerror(err));
97 101 return (MAP_FAILED);
98 102 }
99 103 return (addr);
100 104 }
101 105
102 106 void *
103 107 libld_malloc(size_t size)
104 108 {
105 109 Ld_heap *chp = ld_heap;
106 110 void *vptr;
107 111 size_t asize = size + HEAPALIGN;
108 112
109 113 /*
110 114 * If this is the first allocation, or the allocation request is greater
111 115 * than the current free space available, allocate a new heap.
112 116 */
113 117 if ((chp == NULL) ||
114 118 (((size_t)chp->lh_end - (size_t)chp->lh_free) <= asize)) {
115 119 Ld_heap *nhp;
116 120 size_t hsize = (size_t)S_ROUND(sizeof (Ld_heap), HEAPALIGN);
117 121 size_t tsize = (size_t)S_ROUND((asize + hsize), HEAPALIGN);
118 122
119 123 /*
120 124 * Allocate a block that is at minimum 'HEAPBLOCK' size
121 125 */
122 126 if (tsize < HEAPBLOCK)
123 127 tsize = HEAPBLOCK;
124 128
125 129 if ((nhp = dz_map(tsize)) == MAP_FAILED)
126 130 return (NULL);
127 131
128 132 nhp->lh_next = chp;
129 133 nhp->lh_free = (void *)((size_t)nhp + hsize);
130 134 nhp->lh_end = (void *)((size_t)nhp + tsize);
131 135
132 136 ld_heap = chp = nhp;
133 137 }
134 138 vptr = chp->lh_free;
135 139
136 140 /*
137 141 * Assign size to head of allocated block (used by realloc), and
138 142 * memory arena as then next 8-byte aligned offset.
139 143 */
140 144 *((size_t *)vptr) = size;
141 145 vptr = (void *)((size_t)vptr + HEAPALIGN);
142 146
143 147 /*
144 148 * Increment free to point to next available block
145 149 */
146 150 chp->lh_free = (void *)S_ROUND((size_t)chp->lh_free + asize,
147 151 HEAPALIGN);
148 152
149 153 return (vptr);
150 154 }
151 155
152 156 void *
153 157 libld_realloc(void *ptr, size_t size)
154 158 {
155 159 size_t psize;
156 160 void *vptr;
157 161
158 162 if (ptr == NULL)
159 163 return (libld_malloc(size));
160 164
161 165 /*
162 166 * Size of the allocated blocks is stored *just* before the blocks
163 167 * address.
164 168 */
165 169 psize = *((size_t *)((size_t)ptr - HEAPALIGN));
166 170
167 171 /*
168 172 * If the block actually fits then just return.
169 173 */
170 174 if (size <= psize)
171 175 return (ptr);
172 176
173 177 if ((vptr = libld_malloc(size)) != NULL)
174 178 (void) memcpy(vptr, ptr, psize);
175 179
176 180 return (vptr);
177 181 }
178 182
179 183 void
180 184 /* ARGSUSED 0 */
181 185 libld_free(void *ptr)
182 186 {
183 187 }
184 188
185 189 /*
186 190 * Determine if a shared object definition structure already exists and if
187 191 * not create one. These definitions provide for recording information
188 192 * regarding shared objects that are still to be processed. Once processed
189 193 * shared objects are maintained on the ofl_sos list. The information
190 194 * recorded in this structure includes:
191 195 *
192 196 * o DT_USED requirements. In these cases definitions are added during
193 197 * mapfile processing of `-' entries (see map_dash()).
194 198 *
195 199 * o implicit NEEDED entries. As shared objects are processed from the
196 200 * command line so any of their dependencies are recorded in these
197 201 * structures for later processing (see process_dynamic()).
198 202 *
199 203 * o version requirements. Any explicit shared objects that have version
200 204 * dependencies on other objects have their version requirements recorded.
201 205 * In these cases definitions are added during mapfile processing of `-'
202 206 * entries (see map_dash()). Also, shared objects may have versioning
203 207 * requirements on their NEEDED entries. These cases are added during
204 208 * their version processing (see vers_need_process()).
205 209 *
206 210 * Note: Both process_dynamic() and vers_need_process() may generate the
207 211 * initial version definition structure because you can't rely on what
208 212 * section (.dynamic or .SUNW_version) may be processed first from any
209 213 * input file.
210 214 */
211 215 Sdf_desc *
212 216 sdf_find(const char *name, APlist *alp)
213 217 {
214 218 Aliste idx;
215 219 Sdf_desc *sdf;
216 220
217 221 for (APLIST_TRAVERSE(alp, idx, sdf))
218 222 if (strcmp(name, sdf->sdf_name) == 0)
219 223 return (sdf);
220 224
221 225 return (NULL);
222 226 }
223 227
224 228 Sdf_desc *
225 229 sdf_add(const char *name, APlist **alpp)
226 230 {
227 231 Sdf_desc *sdf;
228 232
229 233 if ((sdf = libld_calloc(sizeof (Sdf_desc), 1)) == NULL)
230 234 return ((Sdf_desc *)S_ERROR);
231 235
232 236 sdf->sdf_name = name;
233 237
234 238 if (aplist_append(alpp, sdf, AL_CNT_OFL_LIBS) == NULL)
235 239 return ((Sdf_desc *)S_ERROR);
236 240
237 241 return (sdf);
238 242 }
239 243
240 244 /*
241 245 * Add a string, separated by a colon, to an existing string. Typically used
242 246 * to maintain filter, rpath and audit names, of which there is normally only
243 247 * one string supplied anyway.
244 248 */
245 249 char *
246 250 add_string(char *old, char *str)
247 251 {
248 252 char *new;
249 253
250 254 if (old) {
251 255 char *_str;
252 256 size_t len;
253 257
254 258 /*
255 259 * If an original string exists, make sure this new string
256 260 * doesn't get duplicated.
257 261 */
258 262 if ((_str = strstr(old, str)) != NULL) {
259 263 if (((_str == old) ||
260 264 (*(_str - 1) == *(MSG_ORIG(MSG_STR_COLON)))) &&
261 265 (_str += strlen(str)) &&
262 266 ((*_str == '\0') ||
263 267 (*_str == *(MSG_ORIG(MSG_STR_COLON)))))
264 268 return (old);
265 269 }
266 270
267 271 len = strlen(old) + strlen(str) + 2;
268 272 if ((new = libld_calloc(1, len)) == NULL)
269 273 return ((char *)S_ERROR);
270 274 (void) snprintf(new, len, MSG_ORIG(MSG_FMT_COLPATH), old, str);
271 275 } else {
272 276 if ((new = libld_malloc(strlen(str) + 1)) == NULL)
273 277 return ((char *)S_ERROR);
274 278 (void) strcpy(new, str);
275 279 }
276 280
277 281 return (new);
278 282 }
279 283
280 284 /*
281 285 * The GNU ld '-wrap=XXX' and '--wrap=XXX' options correspond to our
282 286 * '-z wrap=XXX'. When str2chr() does this conversion, we end up with
283 287 * the return character set to 'z' and optarg set to 'XXX'. This callback
284 288 * changes optarg to include the missing wrap= prefix.
285 289 *
286 290 * exit:
287 291 * Returns c on success, or '?' on error.
288 292 */
289 293 static int
290 294 str2chr_wrap_cb(int c)
291 295 {
292 296 char *str;
293 297 size_t len = MSG_ARG_WRAP_SIZE + strlen(optarg) + 1;
294 298
295 299 if ((str = libld_malloc(len)) == NULL)
296 300 return ('?');
297 301 (void) snprintf(str, len, MSG_ORIG(MSG_FMT_STRCAT),
298 302 MSG_ORIG(MSG_ARG_WRAP), optarg);
299 303 optarg = str;
300 304 return (c);
301 305 }
302 306
303 307 /*
304 308 * Determine whether this string, possibly with an associated option, should
305 309 * be translated to an option character. If so, update the optind and optarg
306 310 * and optopt as described for short options in getopt(3c).
307 311 *
308 312 * entry:
309 313 * lml - Link map list for debug messages
310 314 * ndx - Starting optind for current item
311 315 * argc, argv - Command line arguments
↓ open down ↓ |
270 lines elided |
↑ open up ↑ |
312 316 * arg - Option to be examined
313 317 * c, opt - Option character (c) and corresponding long name (opt)
314 318 * optsz - 0 if option does not accept a value. If option does
315 319 * accept a value, strlen(opt), giving the offset to the
316 320 * value if the option and value are combined in one string.
317 321 * cbfunc - NULL, or pointer to function to call if a translation is
318 322 * successful.
319 323 */
320 324 static int
321 325 str2chr(Lm_list *lml, int ndx, int argc, char **argv, char *arg, int c,
322 - const char *opt, size_t optsz, int cbfunc(int))
326 + const char *opt, size_t optsz, int (*cbfunc)(int))
323 327 {
324 328 if (optsz == 0) {
325 329 /*
326 330 * Compare a single option (ie. there's no associated option
327 331 * argument).
328 332 */
329 333 if (strcmp(arg, opt) == 0) {
330 334 DBG_CALL(Dbg_args_str2chr(lml, ndx, opt, c));
331 335 optind += 1;
332 336 optopt = c;
333 337 return (c);
334 338 }
335 339 } else if ((strcmp(arg, opt) == 0) ||
336 340 ((arg[optsz] == '=') && strncmp(arg, opt, optsz) == 0)) {
337 341 /*
338 342 * Otherwise, compare the option name, which may be
339 343 * concatenated with the option argument.
340 344 */
341 345 DBG_CALL(Dbg_args_str2chr(lml, ndx, opt, c));
342 346
343 347 if (arg[optsz] == '\0') {
344 348 /*
345 349 * Optarg is the next argument (white space separated).
346 350 * Make sure an optarg is available, and if not return
347 351 * a failure to prevent any fall-through to the generic
348 352 * getopt() processing.
349 353 *
350 354 * Since we'll be completely failing this option we
351 355 * don't want to update optopt with the translation,
352 356 * but also need to set it to _something_. Setting it
353 357 * to the '-' of the argument causes us to behave
354 358 * correctly.
355 359 */
356 360 if ((++optind + 1) > argc) {
357 361 optopt = arg[0];
358 362 return ('?');
359 363 }
360 364 optarg = argv[optind];
361 365 optind++;
362 366 } else {
363 367 /*
364 368 * GNU option/option argument pairs can be represented
365 369 * with a "=" separator. If this is the case, remove
366 370 * the separator.
367 371 */
368 372 optarg = &arg[optsz];
369 373 optind++;
370 374 if (*optarg == '=') {
371 375 if (*(++optarg) == '\0') {
372 376 optopt = arg[0];
373 377 return ('?');
374 378 }
375 379 }
376 380 }
377 381
378 382 if (cbfunc != NULL)
379 383 c = (*cbfunc)(c);
380 384 optopt = c;
381 385 return (c);
382 386 }
383 387 return (0);
384 388 }
385 389
386 390 /*
387 391 * Parse an individual option. The intent of this function is to determine if
388 392 * any known, non-Solaris options have been passed to ld(1). This condition
389 393 * can occur as a result of build configuration tools, because of users
390 394 * familiarity with other systems, or simply the users preferences. If a known
391 395 * non-Solaris option can be determined, translate that option into the Solaris
392 396 * counterpart.
393 397 *
394 398 * This function will probably never be a complete solution, as new, non-Solaris
395 399 * options are discovered, their translation will have to be added. Other
396 400 * non-Solaris options are incompatible with the Solaris link-editor, and will
397 401 * never be recognized. We support what we can.
398 402 */
399 403 int
400 404 ld_getopt(Lm_list *lml, int ndx, int argc, char **argv)
401 405 {
402 406 int c;
403 407
404 408 if ((optind < argc) && argv[optind] && (argv[optind][0] == '-')) {
405 409 char *arg = &argv[optind][1];
406 410
407 411 switch (*arg) {
408 412 case 'r':
409 413 /* Translate -rpath <optarg> to -R <optarg> */
410 414 if ((c = str2chr(lml, ndx, argc, argv, arg, 'R',
411 415 MSG_ORIG(MSG_ARG_T_RPATH),
412 416 MSG_ARG_T_RPATH_SIZE, NULL)) != 0) {
413 417 return (c);
414 418 }
415 419 break;
416 420 case 's':
417 421 /* Translate -shared to -G */
418 422 if ((c = str2chr(lml, ndx, argc, argv, arg, 'G',
419 423 MSG_ORIG(MSG_ARG_T_SHARED), 0, NULL)) != 0) {
420 424 return (c);
421 425
422 426 /* Translate -soname <optarg> to -h <optarg> */
423 427 } else if ((c = str2chr(lml, ndx, argc, argv, arg, 'h',
424 428 MSG_ORIG(MSG_ARG_T_SONAME),
425 429 MSG_ARG_T_SONAME_SIZE, NULL)) != 0) {
426 430 return (c);
427 431 }
428 432 break;
429 433 case 'w':
430 434 /* Translate -wrap to -z wrap= */
431 435 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
432 436 MSG_ORIG(MSG_ARG_T_WRAP) + 1,
433 437 MSG_ARG_T_WRAP_SIZE - 1, str2chr_wrap_cb)) != 0) {
434 438 return (c);
435 439 }
436 440 break;
437 441 case '(':
438 442 /*
439 443 * Translate -( to -z rescan-start
440 444 */
441 445 if ((c = str2chr(lml, ndx, argc, argv,
442 446 arg, 'z', MSG_ORIG(MSG_ARG_T_OPAR), 0, NULL)) !=
443 447 0) {
444 448 optarg = (char *)MSG_ORIG(MSG_ARG_RESCAN_START);
445 449 return (c);
446 450 }
447 451 break;
448 452 case ')':
449 453 /*
450 454 * Translate -) to -z rescan-end
451 455 */
452 456 if ((c = str2chr(lml, ndx, argc, argv,
453 457 arg, 'z', MSG_ORIG(MSG_ARG_T_CPAR), 0, NULL)) !=
454 458 0) {
455 459 optarg = (char *)MSG_ORIG(MSG_ARG_RESCAN_END);
456 460 return (c);
457 461 }
458 462 break;
459 463 case '-':
460 464 switch (*(arg + 1)) {
461 465 case 'a':
462 466 /*
463 467 * Translate --allow-multiple-definition to
464 468 * -zmuldefs
465 469 */
466 470 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
467 471 MSG_ORIG(MSG_ARG_T_MULDEFS), 0, NULL)) !=
468 472 0) {
469 473 optarg =
470 474 (char *)MSG_ORIG(MSG_ARG_MULDEFS);
471 475 return (c);
472 476
473 477 /*
474 478 * Translate --auxiliary <optarg> to
475 479 * -f <optarg>
476 480 */
477 481 } else if ((c = str2chr(lml, argc, ndx, argv,
478 482 arg, 'f', MSG_ORIG(MSG_ARG_T_AUXFLTR),
479 483 MSG_ARG_T_AUXFLTR_SIZE, NULL)) != 0) {
480 484 return (c);
481 485 }
482 486 break;
483 487 case 'd':
484 488 /*
485 489 * Translate --dynamic-linker <optarg> to
486 490 * -I <optarg>
487 491 */
488 492 if ((c = str2chr(lml, ndx, argc, argv, arg, 'I',
489 493 MSG_ORIG(MSG_ARG_T_INTERP),
490 494 MSG_ARG_T_INTERP_SIZE, NULL)) != 0) {
491 495 return (c);
492 496 }
493 497 break;
494 498 case 'e':
495 499 /* Translate --entry <optarg> to -e <optarg> */
496 500 if ((c = str2chr(lml, ndx, argc, argv, arg, 'e',
497 501 MSG_ORIG(MSG_ARG_T_ENTRY),
498 502 MSG_ARG_T_ENTRY_SIZE, NULL)) != 0) {
499 503 return (c);
500 504 }
501 505 /*
502 506 * Translate --end-group to -z rescan-end
503 507 */
504 508 if ((c = str2chr(lml, ndx, argc, argv,
505 509 arg, 'z', MSG_ORIG(MSG_ARG_T_ENDGROUP),
506 510 0, NULL)) != 0) {
507 511 optarg = (char *)
508 512 MSG_ORIG(MSG_ARG_RESCAN_END);
509 513 return (c);
510 514 }
511 515 break;
512 516 case 'f':
513 517 /*
514 518 * Translate --fatal-warnings to
515 519 * -z fatal-warnings.
516 520 */
517 521 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
518 522 MSG_ORIG(MSG_ARG_T_FATWARN),
519 523 0, NULL)) != 0) {
520 524 optarg = (char *)
521 525 MSG_ORIG(MSG_ARG_FATWARN);
522 526 return (c);
523 527 }
524 528 /* Translate --filter <optarg> to -F <optarg> */
525 529 if ((c = str2chr(lml, ndx, argc, argv, arg, 'F',
526 530 MSG_ORIG(MSG_ARG_T_STDFLTR),
527 531 MSG_ARG_T_STDFLTR_SIZE, NULL)) != 0) {
528 532 return (c);
529 533 }
530 534 break;
531 535 case 'h':
532 536 /* Translate --help to -zhelp */
533 537 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
534 538 MSG_ORIG(MSG_ARG_T_HELP), 0, NULL)) !=
535 539 0) {
536 540 optarg = (char *)MSG_ORIG(MSG_ARG_HELP);
537 541 return (c);
538 542 }
539 543 break;
540 544 case 'l':
541 545 /*
542 546 * Translate --library <optarg> to -l <optarg>
543 547 */
544 548 if ((c = str2chr(lml, ndx, argc, argv, arg, 'l',
545 549 MSG_ORIG(MSG_ARG_T_LIBRARY),
546 550 MSG_ARG_T_LIBRARY_SIZE, NULL)) != 0) {
547 551 return (c);
548 552
549 553 /*
550 554 * Translate --library-path <optarg> to
551 555 * -L <optarg>
552 556 */
553 557 } else if ((c = str2chr(lml, ndx, argc, argv,
554 558 arg, 'L', MSG_ORIG(MSG_ARG_T_LIBPATH),
555 559 MSG_ARG_T_LIBPATH_SIZE, NULL)) != 0) {
556 560 return (c);
557 561 }
558 562 break;
559 563 case 'n':
560 564 /*
561 565 * Translate --no-fatal-warnings to
562 566 * -z nofatal-warnings.
563 567 */
564 568 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
565 569 MSG_ORIG(MSG_ARG_T_NOFATWARN),
566 570 0, NULL)) != 0) {
567 571 optarg = (char *)
568 572 MSG_ORIG(MSG_ARG_NOFATWARN);
569 573 return (c);
570 574 }
571 575
572 576 /* Translate --no-undefined to -zdefs */
573 577 if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
574 578 MSG_ORIG(MSG_ARG_T_NOUNDEF), 0, NULL)) !=
575 579 0) {
576 580 optarg = (char *)MSG_ORIG(MSG_ARG_DEFS);
577 581 return (c);
578 582
579 583 /*
580 584 * Translate --no-whole-archive to
581 585 * -z defaultextract
582 586 */
583 587 } else if ((c = str2chr(lml, ndx, argc, argv,
584 588 arg, 'z', MSG_ORIG(MSG_ARG_T_NOWHOLEARC),
585 589 0, NULL)) != 0) {
586 590 optarg =
587 591 (char *)MSG_ORIG(MSG_ARG_DFLEXTRT);
588 592 return (c);
589 593 }
590 594 break;
591 595 case 'o':
592 596 /* Translate --output <optarg> to -o <optarg> */
593 597 if ((c = str2chr(lml, ndx, argc, argv, arg, 'o',
594 598 MSG_ORIG(MSG_ARG_T_OUTPUT),
595 599 MSG_ARG_T_OUTPUT_SIZE, NULL)) != 0) {
596 600 return (c);
597 601 }
598 602 break;
599 603 case 'r':
600 604 /* Translate --relocatable to -r */
601 605 if ((c = str2chr(lml, ndx, argc, argv, arg, 'r',
602 606 MSG_ORIG(MSG_ARG_T_RELOCATABLE), 0,
603 607 NULL)) != 0) {
604 608 return (c);
605 609 }
606 610 break;
607 611 case 's':
608 612 /* Translate --strip-all to -s */
609 613 if ((c = str2chr(lml, ndx, argc, argv, arg, 's',
610 614 MSG_ORIG(MSG_ARG_T_STRIP), 0, NULL)) !=
611 615 0) {
612 616 return (c);
613 617 }
614 618 /*
615 619 * Translate --start-group to -z rescan-start
616 620 */
617 621 if ((c = str2chr(lml, ndx, argc, argv,
618 622 arg, 'z', MSG_ORIG(MSG_ARG_T_STARTGROUP),
619 623 0, NULL)) != 0) {
620 624 optarg = (char *)
621 625 MSG_ORIG(MSG_ARG_RESCAN_START);
622 626 return (c);
623 627 }
624 628 break;
625 629 case 'u':
626 630 /*
627 631 * Translate --undefined <optarg> to
628 632 * -u <optarg>
629 633 */
630 634 if ((c = str2chr(lml, ndx, argc, argv, arg, 'u',
631 635 MSG_ORIG(MSG_ARG_T_UNDEF),
632 636 MSG_ARG_T_UNDEF_SIZE, NULL)) != 0) {
633 637 return (c);
634 638 }
635 639 break;
636 640 case 'v':
637 641 /* Translate --version to -V */
638 642 if ((c = str2chr(lml, ndx, argc, argv, arg, 'V',
639 643 MSG_ORIG(MSG_ARG_T_VERSION), 0, NULL)) !=
640 644 0) {
641 645 return (c);
642 646 }
643 647 break;
644 648 case 'w':
645 649 /*
646 650 * Translate --whole-archive to -z alltextract
647 651 */
648 652 if ((c = str2chr(lml, ndx, argc, argv,
649 653 arg, 'z', MSG_ORIG(MSG_ARG_T_WHOLEARC),
650 654 0, NULL)) != 0) {
651 655 optarg =
652 656 (char *)MSG_ORIG(MSG_ARG_ALLEXTRT);
653 657 return (c);
654 658 }
655 659 /*
656 660 * Translate --wrap to -z wrap=
657 661 */
658 662 if ((c = str2chr(lml, ndx, argc, argv,
659 663 arg, 'z', MSG_ORIG(MSG_ARG_T_WRAP),
660 664 MSG_ARG_T_WRAP_SIZE, str2chr_wrap_cb)) !=
661 665 0) {
662 666 return (c);
663 667 }
664 668 break;
665 669 }
666 670 break;
667 671 }
668 672 }
669 673
670 674 if ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
671 675 /*
672 676 * It is possible that a "-Wl," argument has been used to
673 677 * specify an option. This isn't advertized ld(1) syntax, but
674 678 * compiler drivers and configuration tools, have been known to
675 679 * pass this compiler option to ld(1). Strip off the "-Wl,"
676 680 * prefix and pass the option through.
677 681 */
678 682 if ((c == 'W') && (strncmp(optarg,
679 683 MSG_ORIG(MSG_ARG_T_WL), MSG_ARG_T_WL_SIZE) == 0)) {
680 684 DBG_CALL(Dbg_args_Wldel(lml, ndx, optarg));
681 685 c = optarg[MSG_ARG_T_WL_SIZE];
682 686 optarg += MSG_ARG_T_WL_SIZE + 1;
683 687 }
684 688 }
685 689
686 690 return (c);
687 691 }
688 692
689 693 /*
690 694 * A compare routine for Isd_node AVL trees.
691 695 */
692 696 int
693 697 isdavl_compare(const void *n1, const void *n2)
694 698 {
695 699 uint_t hash1, hash2;
696 700 const char *st1, *st2;
697 701 int rc;
698 702
699 703 hash1 = ((Isd_node *)n1)->isd_hash;
700 704 hash2 = ((Isd_node *)n2)->isd_hash;
701 705
702 706 if (hash1 > hash2)
703 707 return (1);
704 708 if (hash1 < hash2)
705 709 return (-1);
706 710
707 711 st1 = ((Isd_node *)n1)->isd_name;
708 712 st2 = ((Isd_node *)n2)->isd_name;
709 713
710 714 rc = strcmp(st1, st2);
711 715 if (rc > 0)
712 716 return (1);
713 717 if (rc < 0)
714 718 return (-1);
715 719 return (0);
716 720 }
717 721
718 722 /*
719 723 * Messaging support - funnel everything through dgettext().
720 724 */
721 725 const char *
722 726 _libld_msg(Msg mid)
723 727 {
724 728 return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid)));
725 729 }
726 730
727 731 /*
728 732 * Determine whether a symbol name should be demangled.
729 733 */
730 734 const char *
731 735 demangle(const char *name)
732 736 {
733 737 if (demangle_flag)
734 738 return (Elf_demangle_name(name));
735 739 else
736 740 return (name);
737 741 }
738 742
739 743 /*
740 744 * Compare a series of platform or machine hardware names.
741 745 */
742 746 int
743 747 cap_names_match(Alist *alp1, Alist *alp2)
744 748 {
745 749 Capstr *capstr1;
746 750 Aliste idx1;
747 751 int match = 0;
748 752 Word nitems;
749 753
750 754 if ((nitems = alist_nitems(alp1)) != alist_nitems(alp2))
751 755 return (1);
752 756
753 757 for (ALIST_TRAVERSE(alp1, idx1, capstr1)) {
754 758 Capstr *capstr2;
755 759 Aliste idx2;
756 760
757 761 for (ALIST_TRAVERSE(alp2, idx2, capstr2)) {
758 762 if (strcmp(capstr1->cs_str, capstr2->cs_str))
759 763 continue;
760 764
761 765 match++;
762 766 break;
763 767 }
764 768 }
765 769
766 770 if (nitems == match)
767 771 return (0);
768 772
769 773 return (1);
770 774 }
↓ open down ↓ |
438 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX