Rev 5197 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5197 | Rev 6324 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* BFD back-end for archive files (libraries). |
1 | /* BFD back-end for archive files (libraries). |
2 | Copyright 1990-2013 Free Software Foundation, Inc. |
2 | Copyright (C) 1990-2015 Free Software Foundation, Inc. |
3 | Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. |
3 | Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault. |
Line 4... | Line 4... | ||
4 | 4 | ||
Line 5... | Line 5... | ||
5 | This file is part of BFD, the Binary File Descriptor library. |
5 | This file is part of BFD, the Binary File Descriptor library. |
Line 138... | Line 138... | ||
138 | #include "aout/ar.h" |
138 | #include "aout/ar.h" |
139 | #include "aout/ranlib.h" |
139 | #include "aout/ranlib.h" |
140 | #include "safe-ctype.h" |
140 | #include "safe-ctype.h" |
141 | #include "hashtab.h" |
141 | #include "hashtab.h" |
142 | #include "filenames.h" |
142 | #include "filenames.h" |
- | 143 | #include "bfdlink.h" |
|
Line 143... | Line 144... | ||
143 | 144 | ||
144 | #ifndef errno |
145 | #ifndef errno |
145 | extern int errno; |
146 | extern int errno; |
Line 308... | Line 309... | ||
308 | if (hash_table) |
309 | if (hash_table) |
309 | { |
310 | { |
310 | struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m); |
311 | struct ar_cache *entry = (struct ar_cache *) htab_find (hash_table, &m); |
311 | if (!entry) |
312 | if (!entry) |
312 | return NULL; |
313 | return NULL; |
- | 314 | ||
- | 315 | /* Unfortunately this flag is set after checking that we have |
|
- | 316 | an archive, and checking for an archive means one element has |
|
313 | else |
317 | sneaked into the cache. */ |
- | 318 | entry->arbfd->no_export = arch_bfd->no_export; |
|
314 | return entry->arbfd; |
319 | return entry->arbfd; |
315 | } |
320 | } |
316 | else |
321 | else |
317 | return NULL; |
322 | return NULL; |
318 | } |
323 | } |
Line 372... | Line 377... | ||
372 | 377 | ||
373 | return TRUE; |
378 | return TRUE; |
374 | } |
379 | } |
375 | 380 | ||
376 | static bfd * |
381 | static bfd * |
377 | _bfd_find_nested_archive (bfd *arch_bfd, const char *filename) |
382 | open_nested_file (const char *filename, bfd *archive) |
378 | { |
- | |
379 | bfd *abfd; |
383 | { |
- | 384 | const char *target; |
|
- | 385 | bfd *n_bfd; |
|
- | 386 | ||
- | 387 | target = NULL; |
|
- | 388 | if (!archive->target_defaulted) |
|
- | 389 | target = archive->xvec->name; |
|
- | 390 | n_bfd = bfd_openr (filename, target); |
|
- | 391 | if (n_bfd != NULL) |
|
- | 392 | { |
|
- | 393 | n_bfd->lto_output = archive->lto_output; |
|
- | 394 | n_bfd->no_export = archive->no_export; |
|
- | 395 | } |
|
- | 396 | return n_bfd; |
|
- | 397 | } |
|
- | 398 | ||
- | 399 | static bfd * |
|
- | 400 | find_nested_archive (const char *filename, bfd *arch_bfd) |
|
- | 401 | { |
|
Line 380... | Line 402... | ||
380 | const char *target; |
402 | bfd *abfd; |
381 | 403 | ||
382 | /* PR 15140: Don't allow a nested archive pointing to itself. */ |
404 | /* PR 15140: Don't allow a nested archive pointing to itself. */ |
383 | if (filename_cmp (filename, arch_bfd->filename) == 0) |
405 | if (filename_cmp (filename, arch_bfd->filename) == 0) |
Line 391... | Line 413... | ||
391 | abfd = abfd->archive_next) |
413 | abfd = abfd->archive_next) |
392 | { |
414 | { |
393 | if (filename_cmp (filename, abfd->filename) == 0) |
415 | if (filename_cmp (filename, abfd->filename) == 0) |
394 | return abfd; |
416 | return abfd; |
395 | } |
417 | } |
396 | target = NULL; |
- | |
397 | if (!arch_bfd->target_defaulted) |
- | |
398 | target = arch_bfd->xvec->name; |
- | |
399 | abfd = bfd_openr (filename, target); |
418 | abfd = open_nested_file (filename, arch_bfd); |
400 | if (abfd) |
419 | if (abfd) |
401 | { |
420 | { |
402 | abfd->archive_next = arch_bfd->nested_archives; |
421 | abfd->archive_next = arch_bfd->nested_archives; |
403 | arch_bfd->nested_archives = abfd; |
422 | arch_bfd->nested_archives = abfd; |
404 | } |
423 | } |
Line 623... | Line 642... | ||
623 | 642 | ||
624 | bfd * |
643 | bfd * |
625 | _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) |
644 | _bfd_get_elt_at_filepos (bfd *archive, file_ptr filepos) |
626 | { |
645 | { |
627 | struct areltdata *new_areldata; |
646 | struct areltdata *new_areldata; |
628 | bfd *n_nfd; |
647 | bfd *n_bfd; |
Line 629... | Line 648... | ||
629 | char *filename; |
648 | char *filename; |
630 | 649 | ||
631 | n_nfd = _bfd_look_for_bfd_in_cache (archive, filepos); |
650 | n_bfd = _bfd_look_for_bfd_in_cache (archive, filepos); |
Line 632... | Line 651... | ||
632 | if (n_nfd) |
651 | if (n_bfd) |
633 | return n_nfd; |
652 | return n_bfd; |
Line 634... | Line 653... | ||
634 | 653 | ||
Line 640... | Line 659... | ||
640 | 659 | ||
Line 641... | Line 660... | ||
641 | filename = new_areldata->filename; |
660 | filename = new_areldata->filename; |
642 | 661 | ||
643 | if (bfd_is_thin_archive (archive)) |
- | |
644 | { |
- | |
645 | const char *target; |
662 | if (bfd_is_thin_archive (archive)) |
646 | 663 | { |
|
647 | /* This is a proxy entry for an external file. */ |
664 | /* This is a proxy entry for an external file. */ |
648 | if (! IS_ABSOLUTE_PATH (filename)) |
665 | if (! IS_ABSOLUTE_PATH (filename)) |
649 | { |
666 | { |
Line 657... | Line 674... | ||
657 | 674 | ||
658 | if (new_areldata->origin > 0) |
675 | if (new_areldata->origin > 0) |
659 | { |
676 | { |
660 | /* This proxy entry refers to an element of a nested archive. |
677 | /* This proxy entry refers to an element of a nested archive. |
661 | Locate the member of that archive and return a bfd for it. */ |
678 | Locate the member of that archive and return a bfd for it. */ |
Line 662... | Line 679... | ||
662 | bfd *ext_arch = _bfd_find_nested_archive (archive, filename); |
679 | bfd *ext_arch = find_nested_archive (filename, archive); |
663 | 680 | ||
664 | if (ext_arch == NULL |
681 | if (ext_arch == NULL |
665 | || ! bfd_check_format (ext_arch, bfd_archive)) |
682 | || ! bfd_check_format (ext_arch, bfd_archive)) |
666 | { |
683 | { |
667 | free (new_areldata); |
684 | free (new_areldata); |
668 | return NULL; |
685 | return NULL; |
669 | } |
686 | } |
670 | n_nfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin); |
687 | n_bfd = _bfd_get_elt_at_filepos (ext_arch, new_areldata->origin); |
671 | if (n_nfd == NULL) |
688 | if (n_bfd == NULL) |
672 | { |
689 | { |
673 | free (new_areldata); |
690 | free (new_areldata); |
674 | return NULL; |
691 | return NULL; |
675 | } |
692 | } |
676 | n_nfd->proxy_origin = bfd_tell (archive); |
693 | n_bfd->proxy_origin = bfd_tell (archive); |
- | 694 | return n_bfd; |
|
677 | return n_nfd; |
695 | } |
678 | } |
696 | |
679 | /* It's not an element of a nested archive; |
- | |
680 | open the external file as a bfd. */ |
- | |
681 | target = NULL; |
- | |
682 | if (!archive->target_defaulted) |
697 | /* It's not an element of a nested archive; |
683 | target = archive->xvec->name; |
698 | open the external file as a bfd. */ |
684 | n_nfd = bfd_openr (filename, target); |
699 | n_bfd = open_nested_file (filename, archive); |
685 | if (n_nfd == NULL) |
700 | if (n_bfd == NULL) |
686 | bfd_set_error (bfd_error_malformed_archive); |
701 | bfd_set_error (bfd_error_malformed_archive); |
687 | } |
702 | } |
688 | else |
703 | else |
689 | { |
704 | { |
Line 690... | Line 705... | ||
690 | n_nfd = _bfd_create_empty_archive_element_shell (archive); |
705 | n_bfd = _bfd_create_empty_archive_element_shell (archive); |
691 | } |
706 | } |
692 | 707 | ||
693 | if (n_nfd == NULL) |
708 | if (n_bfd == NULL) |
694 | { |
709 | { |
Line 695... | Line 710... | ||
695 | free (new_areldata); |
710 | free (new_areldata); |
Line 696... | Line 711... | ||
696 | return NULL; |
711 | return NULL; |
697 | } |
712 | } |
698 | 713 | ||
699 | n_nfd->proxy_origin = bfd_tell (archive); |
714 | n_bfd->proxy_origin = bfd_tell (archive); |
700 | 715 | ||
701 | if (bfd_is_thin_archive (archive)) |
716 | if (bfd_is_thin_archive (archive)) |
702 | { |
717 | { |
703 | n_nfd->origin = 0; |
718 | n_bfd->origin = 0; |
704 | } |
719 | } |
Line 705... | Line 720... | ||
705 | else |
720 | else |
Line 706... | Line 721... | ||
706 | { |
721 | { |
707 | n_nfd->origin = n_nfd->proxy_origin; |
722 | n_bfd->origin = n_bfd->proxy_origin; |
- | 723 | n_bfd->filename = xstrdup (filename); |
|
- | 724 | } |
|
Line -... | Line 725... | ||
- | 725 | ||
- | 726 | n_bfd->arelt_data = new_areldata; |
|
- | 727 | ||
708 | n_nfd->filename = filename; |
728 | /* Copy BFD_COMPRESS, BFD_DECOMPRESS and BFD_COMPRESS_GABI flags. */ |
709 | } |
729 | n_bfd->flags |= archive->flags & (BFD_COMPRESS |
Line 710... | Line 730... | ||
710 | 730 | | BFD_DECOMPRESS |
|
711 | n_nfd->arelt_data = new_areldata; |
731 | | BFD_COMPRESS_GABI); |
712 | 732 | ||
713 | /* Copy BFD_COMPRESS and BFD_DECOMPRESS flags. */ |
733 | /* Copy is_linker_input. */ |
Line 714... | Line 734... | ||
714 | n_nfd->flags |= archive->flags & (BFD_COMPRESS | BFD_DECOMPRESS); |
734 | n_bfd->is_linker_input = archive->is_linker_input; |
715 | 735 | ||
Line 764... | Line 784... | ||
764 | } |
784 | } |
Line 765... | Line 785... | ||
765 | 785 | ||
766 | bfd * |
786 | bfd * |
767 | bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file) |
787 | bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file) |
768 | { |
788 | { |
Line 769... | Line 789... | ||
769 | file_ptr filestart; |
789 | ufile_ptr filestart; |
770 | 790 | ||
771 | if (!last_file) |
791 | if (!last_file) |
772 | filestart = bfd_ardata (archive)->first_file_filepos; |
792 | filestart = bfd_ardata (archive)->first_file_filepos; |
773 | else |
- | |
774 | { |
- | |
775 | bfd_size_type size = arelt_size (last_file); |
793 | else |
776 | 794 | { |
|
- | 795 | filestart = last_file->proxy_origin; |
|
- | 796 | if (! bfd_is_thin_archive (archive)) |
|
- | 797 | { |
|
777 | filestart = last_file->proxy_origin; |
798 | bfd_size_type size = arelt_size (last_file); |
778 | if (! bfd_is_thin_archive (archive)) |
799 | |
779 | filestart += size; |
800 | filestart += size; |
780 | /* Pad to an even boundary... |
801 | /* Pad to an even boundary... |
781 | Note that last_file->origin can be odd in the case of |
802 | Note that last_file->origin can be odd in the case of |
- | 803 | BSD-4.4-style element with a long odd size. */ |
|
- | 804 | filestart += filestart % 2; |
|
- | 805 | if (filestart <= last_file->proxy_origin) |
|
- | 806 | { |
|
- | 807 | /* Prevent looping. See PR19256. */ |
|
- | 808 | bfd_set_error (bfd_error_malformed_archive); |
|
- | 809 | return NULL; |
|
782 | BSD-4.4-style element with a long odd size. */ |
810 | } |
Line 783... | Line 811... | ||
783 | filestart += filestart % 2; |
811 | } |
784 | } |
812 | } |
Line 899... | Line 927... | ||
899 | mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); |
927 | mapdata = (struct areltdata *) _bfd_read_ar_hdr (abfd); |
900 | if (mapdata == NULL) |
928 | if (mapdata == NULL) |
901 | return FALSE; |
929 | return FALSE; |
902 | parsed_size = mapdata->parsed_size; |
930 | parsed_size = mapdata->parsed_size; |
903 | free (mapdata); |
931 | free (mapdata); |
- | 932 | /* PR 17512: file: 883ff754. */ |
|
- | 933 | /* PR 17512: file: 0458885f. */ |
|
- | 934 | if (parsed_size < 4) |
|
- | 935 | return FALSE; |
|
Line 904... | Line 936... | ||
904 | 936 | ||
905 | raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); |
937 | raw_armap = (bfd_byte *) bfd_zalloc (abfd, parsed_size); |
906 | if (raw_armap == NULL) |
938 | if (raw_armap == NULL) |
Line 914... | Line 946... | ||
914 | bfd_release (abfd, raw_armap); |
946 | bfd_release (abfd, raw_armap); |
915 | return FALSE; |
947 | return FALSE; |
916 | } |
948 | } |
Line 917... | Line 949... | ||
917 | 949 | ||
918 | ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; |
- | |
919 | 950 | ardata->symdef_count = H_GET_32 (abfd, raw_armap) / BSD_SYMDEF_SIZE; |
|
920 | if (ardata->symdef_count * BSD_SYMDEF_SIZE > |
951 | if (ardata->symdef_count * BSD_SYMDEF_SIZE > |
921 | parsed_size - BSD_SYMDEF_COUNT_SIZE) |
952 | parsed_size - BSD_SYMDEF_COUNT_SIZE) |
922 | { |
953 | { |
923 | /* Probably we're using the wrong byte ordering. */ |
954 | /* Probably we're using the wrong byte ordering. */ |
Line 1035... | Line 1066... | ||
1035 | bfd_set_error (bfd_error_malformed_archive); |
1066 | bfd_set_error (bfd_error_malformed_archive); |
1036 | goto release_raw_armap; |
1067 | goto release_raw_armap; |
1037 | } |
1068 | } |
Line 1038... | Line 1069... | ||
1038 | 1069 | ||
1039 | /* OK, build the carsyms. */ |
1070 | /* OK, build the carsyms. */ |
1040 | for (i = 0; i < nsymz; i++) |
1071 | for (i = 0; i < nsymz && stringsize > 0; i++) |
- | 1072 | { |
|
- | 1073 | bfd_size_type len; |
|
1041 | { |
1074 | |
1042 | rawptr = raw_armap + i; |
1075 | rawptr = raw_armap + i; |
1043 | carsyms->file_offset = swap ((bfd_byte *) rawptr); |
1076 | carsyms->file_offset = swap ((bfd_byte *) rawptr); |
- | 1077 | carsyms->name = stringbase; |
|
1044 | carsyms->name = stringbase; |
1078 | /* PR 17512: file: 4a1d50c1. */ |
- | 1079 | len = strnlen (stringbase, stringsize); |
|
- | 1080 | if (len < stringsize) |
|
- | 1081 | len ++; |
|
- | 1082 | stringbase += len; |
|
1045 | stringbase += strlen (stringbase) + 1; |
1083 | stringsize -= len; |
1046 | carsyms++; |
1084 | carsyms++; |
1047 | } |
1085 | } |
Line 1048... | Line 1086... | ||
1048 | *stringbase = 0; |
1086 | *stringbase = 0; |
Line 1128... | Line 1166... | ||
1128 | /* Read the extended name. We know its length. */ |
1166 | /* Read the extended name. We know its length. */ |
1129 | if (bfd_bread (extname, 20, abfd) != 20) |
1167 | if (bfd_bread (extname, 20, abfd) != 20) |
1130 | return FALSE; |
1168 | return FALSE; |
1131 | if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0) |
1169 | if (bfd_seek (abfd, -(file_ptr) (sizeof (hdr) + 20), SEEK_CUR) != 0) |
1132 | return FALSE; |
1170 | return FALSE; |
- | 1171 | extname[20] = 0; |
|
1133 | if (CONST_STRNEQ (extname, "__.SYMDEF SORTED") |
1172 | if (CONST_STRNEQ (extname, "__.SYMDEF SORTED") |
1134 | || CONST_STRNEQ (extname, "__.SYMDEF")) |
1173 | || CONST_STRNEQ (extname, "__.SYMDEF")) |
1135 | return do_slurp_bsd_armap (abfd); |
1174 | return do_slurp_bsd_armap (abfd); |
1136 | } |
1175 | } |
Line 1297... | Line 1336... | ||
1297 | bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1); |
1336 | bfd_ardata (abfd)->extended_names = (char *) bfd_zalloc (abfd, amt + 1); |
1298 | if (bfd_ardata (abfd)->extended_names == NULL) |
1337 | if (bfd_ardata (abfd)->extended_names == NULL) |
1299 | { |
1338 | { |
1300 | byebye: |
1339 | byebye: |
1301 | free (namedata); |
1340 | free (namedata); |
- | 1341 | bfd_ardata (abfd)->extended_names = NULL; |
|
- | 1342 | bfd_ardata (abfd)->extended_names_size = 0; |
|
1302 | return FALSE; |
1343 | return FALSE; |
1303 | } |
1344 | } |
Line 1304... | Line 1345... | ||
1304 | 1345 | ||
1305 | if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt) |
1346 | if (bfd_bread (bfd_ardata (abfd)->extended_names, amt, abfd) != amt) |
Line 1313... | Line 1354... | ||
1313 | 1354 | ||
1314 | /* Since the archive is supposed to be printable if it contains |
1355 | /* Since the archive is supposed to be printable if it contains |
1315 | text, the entries in the list are newline-padded, not null |
1356 | text, the entries in the list are newline-padded, not null |
1316 | padded. In SVR4-style archives, the names also have a |
1357 | padded. In SVR4-style archives, the names also have a |
1317 | trailing '/'. DOS/NT created archive often have \ in them |
1358 | trailing '/'. DOS/NT created archive often have \ in them |
1318 | We'll fix all problems here.. */ |
1359 | We'll fix all problems here. */ |
1319 | { |
1360 | { |
1320 | char *ext_names = bfd_ardata (abfd)->extended_names; |
1361 | char *ext_names = bfd_ardata (abfd)->extended_names; |
1321 | char *temp = ext_names; |
1362 | char *temp = ext_names; |
- | 1363 | char *limit = temp + namedata->parsed_size; |
|
1322 | char *limit = temp + namedata->parsed_size; |
1364 | |
1323 | for (; temp < limit; ++temp) |
1365 | for (; temp < limit; ++temp) |
1324 | { |
1366 | { |
1325 | if (*temp == ARFMAG[1]) |
1367 | if (*temp == ARFMAG[1]) |
1326 | temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0'; |
1368 | temp[temp > ext_names && temp[-1] == '/' ? -1 : 0] = '\0'; |
Line 1958... | Line 2000... | ||
1958 | bfd_set_error (bfd_error_invalid_operation); |
2000 | bfd_set_error (bfd_error_invalid_operation); |
1959 | return -1; |
2001 | return -1; |
1960 | } |
2002 | } |
Line 1961... | Line 2003... | ||
1961 | 2003 | ||
- | 2004 | hdr = arch_hdr (abfd); |
|
- | 2005 | /* PR 17512: file: 3d9e9fe9. */ |
|
1962 | hdr = arch_hdr (abfd); |
2006 | if (hdr == NULL) |
1963 | 2007 | return -1; |
|
1964 | #define foo(arelt, stelt, size) \ |
2008 | #define foo(arelt, stelt, size) \ |
1965 | buf->stelt = strtol (hdr->arelt, &aloser, size); \ |
2009 | buf->stelt = strtol (hdr->arelt, &aloser, size); \ |
1966 | if (aloser == hdr->arelt) \ |
2010 | if (aloser == hdr->arelt) \ |
Line 2354... | Line 2398... | ||
2354 | goto error_return; |
2398 | goto error_return; |
Line 2355... | Line 2399... | ||
2355 | 2399 | ||
2356 | map = new_map; |
2400 | map = new_map; |
Line -... | Line 2401... | ||
- | 2401 | } |
|
- | 2402 | ||
- | 2403 | if (strcmp (syms[src_count]->name, "__gnu_lto_slim") == 0) |
|
- | 2404 | (*_bfd_error_handler) |
|
2357 | } |
2405 | (_("%s: plugin needed to handle lto object"), |
2358 | 2406 | bfd_get_filename (current)); |
|
2359 | namelen = strlen (syms[src_count]->name); |
2407 | namelen = strlen (syms[src_count]->name); |
2360 | amt = sizeof (char *); |
2408 | amt = sizeof (char *); |
2361 | map[orl_count].name = (char **) bfd_alloc (arch, amt); |
2409 | map[orl_count].name = (char **) bfd_alloc (arch, amt); |
Line 2749... | Line 2797... | ||
2749 | BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd); |
2797 | BFD_ASSERT (((struct ar_cache *) *slot)->arbfd == abfd); |
2750 | htab_clear_slot (htab, slot); |
2798 | htab_clear_slot (htab, slot); |
2751 | } |
2799 | } |
2752 | } |
2800 | } |
2753 | } |
2801 | } |
- | 2802 | if (abfd->is_linker_output) |
|
- | 2803 | (*abfd->link.hash->hash_table_free) (abfd); |
|
- | 2804 | ||
2754 | return TRUE; |
2805 | return TRUE; |
2755 | }>>>=>>>>>>>>=>>=>>>=>=><=>>=><=>>>>>>>>>>=>> |
2806 | }>>>=>>>>>>>>=>>=>>>=>=><=>>=><=>>>>>>>>>>>=>>>=> |