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