Changeset 1973 for binutils/trunk/bfd/coffgen.c
- Timestamp:
- Feb 6, 2017, 1:00:00 PM (8 years ago)
- Location:
- binutils/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
binutils/trunk ¶
-
Property svn:mergeinfo
set to
/binutils/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
TabularUnified binutils/trunk/bfd/coffgen.c ¶
r970 r1973 1 1 /* Support for the generic parts of COFF, for BFD. 2 Copyright (C) 1990-201 4Free Software Foundation, Inc.2 Copyright (C) 1990-2016 Free Software Foundation, Inc. 3 3 Written by Cygnus Support. 4 4 … … 147 147 .zdebug_*, after the section flags is set. */ 148 148 if ((flags & SEC_DEBUGGING) 149 && strlen (name) > 7 149 150 && ((name[1] == 'd' && name[6] == '_') 150 || ( name[1] == 'z' && name[7] == '_')))151 || (strlen (name) > 8 && name[1] == 'z' && name[7] == '_'))) 151 152 { 152 153 enum { nothing, compress, decompress } action = nothing; … … 178 179 return FALSE; 179 180 } 180 if ( name[1] != 'z')181 if (return_section->compress_status == COMPRESS_SECTION_DONE) 181 182 { 182 unsigned int len = strlen (name); 183 184 new_name = bfd_alloc (abfd, len + 2); 185 if (new_name == NULL) 186 return FALSE; 187 new_name[0] = '.'; 188 new_name[1] = 'z'; 189 memcpy (new_name + 2, name + 1, len); 183 if (name[1] != 'z') 184 { 185 unsigned int len = strlen (name); 186 187 new_name = bfd_alloc (abfd, len + 2); 188 if (new_name == NULL) 189 return FALSE; 190 new_name[0] = '.'; 191 new_name[1] = 'z'; 192 memcpy (new_name + 2, name + 1, len); 193 } 190 194 } 191 195 break; 192 196 case decompress: 193 197 if (!bfd_init_section_decompress_status (abfd, return_section)) … … 366 370 return NULL; 367 371 } 372 /* PR 17512: file: 11056-1136-0.004. */ 373 if (internal_f.f_opthdr < aoutsz) 374 memset (((char *) opthdr) + internal_f.f_opthdr, 0, aoutsz - internal_f.f_opthdr); 375 368 376 bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a); 369 377 bfd_release (abfd, opthdr); … … 464 472 return NULL; 465 473 } 466 if (sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd)) 474 /* PR 17910: Only check for string overflow if the length has been set. 475 Some DLLs, eg those produced by Visual Studio, may not set the length field. */ 476 if (obj_coff_strings_len (abfd) > 0 477 && sym->_n._n_n._n_offset >= obj_coff_strings_len (abfd)) 467 478 return NULL; 468 479 return strings + sym->_n._n_n._n_offset; … … 627 638 628 639 return total; 629 }630 631 /* Takes a bfd and a symbol, returns a pointer to the coff specific632 area of the symbol if there is one. */633 634 coff_symbol_type *635 coff_symbol_from (bfd *ignore_abfd ATTRIBUTE_UNUSED,636 asymbol *symbol)637 {638 if (!bfd_family_coff (bfd_asymbol_bfd (symbol)))639 return (coff_symbol_type *) NULL;640 641 if (bfd_asymbol_bfd (symbol)->tdata.coff_obj_data == (coff_data_type *) NULL)642 return (coff_symbol_type *) NULL;643 644 return (coff_symbol_type *) symbol;645 640 } 646 641 … … 761 756 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 762 757 { 763 coff_symbol_type *coff_symbol_ptr = coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); 764 758 coff_symbol_type *coff_symbol_ptr; 759 760 coff_symbol_ptr = coff_symbol_from (symbol_ptr_ptr[symbol_index]); 765 761 symbol_ptr_ptr[symbol_index]->udata.i = symbol_index; 766 762 if (coff_symbol_ptr && coff_symbol_ptr->native) … … 806 802 for (symbol_index = 0; symbol_index < symbol_count; symbol_index++) 807 803 { 808 coff_symbol_type *coff_symbol_ptr =809 coff_symbol_from (bfd_ptr, symbol_ptr_ptr[symbol_index]); 810 804 coff_symbol_type *coff_symbol_ptr; 805 806 coff_symbol_ptr = coff_symbol_from (symbol_ptr_ptr[symbol_index]); 811 807 if (coff_symbol_ptr && coff_symbol_ptr->native) 812 808 { … … 1071 1067 asymbol *symbol, 1072 1068 struct internal_syment *isym, 1069 union internal_auxent *iaux, 1073 1070 bfd_vma *written, 1074 1071 bfd_size_type *string_size_p, … … 1136 1133 FIXME: Why? */ 1137 1134 { 1138 coff_symbol_type *c = coff_symbol_from ( abfd,symbol);1135 coff_symbol_type *c = coff_symbol_from (symbol); 1139 1136 if (c != (coff_symbol_type *) NULL) 1140 1137 native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags; … … 1156 1153 if (isym != NULL) 1157 1154 *isym = native->u.syment; 1155 if (iaux != NULL && native->u.syment.n_numaux) 1156 *iaux = native[1].u.auxent; 1158 1157 return ret; 1159 1158 } … … 1268 1267 { 1269 1268 asymbol *symbol = *p; 1270 coff_symbol_type *c_symbol = coff_symbol_from ( abfd,symbol);1269 coff_symbol_type *c_symbol = coff_symbol_from (symbol); 1271 1270 1272 1271 if (c_symbol == (coff_symbol_type *) NULL 1273 1272 || c_symbol->native == (combined_entry_type *) NULL) 1274 1273 { 1275 if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,1274 if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written, 1276 1275 &string_size, &debug_string_section, 1277 1276 &debug_string_size)) … … 1368 1367 asymbol *q = *p; 1369 1368 size_t name_length = strlen (q->name); 1370 coff_symbol_type *c_symbol = coff_symbol_from ( abfd,q);1369 coff_symbol_type *c_symbol = coff_symbol_from (q); 1371 1370 size_t maxlen; 1372 1371 … … 1386 1385 else if (! c_symbol->native->is_sym) 1387 1386 maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN; 1388 1387 1389 1388 else if (bfd_coff_symname_in_debug (abfd, 1390 1389 &c_symbol->native->u.syment)) … … 1712 1711 1713 1712 strings = (char *) bfd_malloc (strsize + 1); 1713 if (strings == NULL) 1714 return NULL; 1715 1714 1716 /* PR 17521 file: 079-54929-0.004. 1715 1717 A corrupt file could contain an index that points into the first … … 1717 1719 they are zero. */ 1718 1720 memset (strings, 0, STRING_SIZE_SIZE); 1719 1720 if (strings == NULL)1721 return NULL;1722 1721 1723 1722 if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd) … … 1787 1786 return NULL; 1788 1787 internal_end = internal + obj_raw_syment_count (abfd); 1789 1788 1790 1789 raw_src = (char *) obj_coff_external_syms (abfd); 1791 1790 … … 1809 1808 internal_ptr->is_sym = TRUE; 1810 1809 1810 /* PR 17512: file: 1353-1166-0.004. */ 1811 if (symbol_ptr->u.syment.n_sclass == C_FILE 1812 && symbol_ptr->u.syment.n_numaux > 0 1813 && raw_src + symesz + symbol_ptr->u.syment.n_numaux 1814 * symesz > raw_end) 1815 { 1816 bfd_release (abfd, internal); 1817 return NULL; 1818 } 1819 1811 1820 for (i = 0; 1812 1821 i < symbol_ptr->u.syment.n_numaux; … … 1816 1825 /* PR 17512: Prevent buffer overrun. */ 1817 1826 if (internal_ptr >= internal_end) 1818 return NULL; 1827 { 1828 bfd_release (abfd, internal); 1829 return NULL; 1830 } 1819 1831 1820 1832 raw_src += symesz; … … 1824 1836 (int) i, symbol_ptr->u.syment.n_numaux, 1825 1837 &(internal_ptr->u.auxent)); 1838 1826 1839 internal_ptr->is_sym = FALSE; 1827 1840 coff_pointerize_aux (abfd, internal, symbol_ptr, i, … … 2026 2039 } 2027 2040 2028 /* Return the COFF syment for a symbol. */2029 2030 bfd_boolean2031 bfd_coff_get_syment (bfd *abfd,2032 asymbol *symbol,2033 struct internal_syment *psyment)2034 {2035 coff_symbol_type *csym;2036 2037 csym = coff_symbol_from (abfd, symbol);2038 if (csym == NULL || csym->native == NULL2039 || ! csym->native->is_sym)2040 {2041 bfd_set_error (bfd_error_invalid_operation);2042 return FALSE;2043 }2044 2045 *psyment = csym->native->u.syment;2046 2047 if (csym->native->fix_value)2048 psyment->n_value = psyment->n_value -2049 (bfd_hostptr_t) obj_raw_syments (abfd);2050 2051 /* FIXME: We should handle fix_line here. */2052 2053 return TRUE;2054 }2055 2056 /* Return the COFF auxent for a symbol. */2057 2058 bfd_boolean2059 bfd_coff_get_auxent (bfd *abfd,2060 asymbol *symbol,2061 int indx,2062 union internal_auxent *pauxent)2063 {2064 coff_symbol_type *csym;2065 combined_entry_type *ent;2066 2067 csym = coff_symbol_from (abfd, symbol);2068 2069 if (csym == NULL2070 || csym->native == NULL2071 || ! csym->native->is_sym2072 || indx >= csym->native->u.syment.n_numaux)2073 {2074 bfd_set_error (bfd_error_invalid_operation);2075 return FALSE;2076 }2077 2078 ent = csym->native + indx + 1;2079 2080 BFD_ASSERT (! ent->is_sym);2081 *pauxent = ent->u.auxent;2082 2083 if (ent->fix_tag)2084 pauxent->x_sym.x_tagndx.l =2085 ((combined_entry_type *) pauxent->x_sym.x_tagndx.p2086 - obj_raw_syments (abfd));2087 2088 if (ent->fix_end)2089 pauxent->x_sym.x_fcnary.x_fcn.x_endndx.l =2090 ((combined_entry_type *) pauxent->x_sym.x_fcnary.x_fcn.x_endndx.p2091 - obj_raw_syments (abfd));2092 2093 if (ent->fix_scnlen)2094 pauxent->x_csect.x_scnlen.l =2095 ((combined_entry_type *) pauxent->x_csect.x_scnlen.p2096 - obj_raw_syments (abfd));2097 2098 return TRUE;2099 }2100 2101 2041 /* Print out information about COFF symbol. */ 2102 2042 … … 2311 2251 return TRUE; 2312 2252 2253 /* If the DWARF lookup failed, but there is DWARF information available 2254 then the problem might be that the file has been rebased. This tool 2255 changes the VMAs of all the sections, but it does not update the DWARF 2256 information. So try again, using a bias against the address sought. */ 2257 if (coff_data (abfd)->dwarf2_find_line_info != NULL) 2258 { 2259 bfd_signed_vma bias; 2260 2261 bias = _bfd_dwarf2_find_symbol_bias (symbols, 2262 & coff_data (abfd)->dwarf2_find_line_info); 2263 2264 if (bias 2265 && _bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, 2266 offset + bias, 2267 filename_ptr, functionname_ptr, 2268 line_ptr, NULL, debug_sections, 0, 2269 &coff_data(abfd)->dwarf2_find_line_info)) 2270 return TRUE; 2271 } 2272 2313 2273 *filename_ptr = 0; 2314 2274 *functionname_ptr = 0; … … 2530 2490 size_t size; 2531 2491 2532 if (! info->relocatable)2492 if (!bfd_link_relocatable (info)) 2533 2493 size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd); 2534 2494 else … … 2548 2508 coff_symbol_type * csym; 2549 2509 2550 csym = coff_symbol_from ( abfd,symbol);2510 csym = coff_symbol_from (symbol); 2551 2511 if (csym == NULL) 2552 2512 { … … 2602 2562 2603 2563 return TRUE; 2604 }2605 2606 struct coff_comdat_info *2607 bfd_coff_get_comdat_section (bfd *abfd, struct bfd_section *sec)2608 {2609 if (bfd_get_flavour (abfd) == bfd_target_coff_flavour2610 && coff_section_data (abfd, sec) != NULL)2611 return coff_section_data (abfd, sec)->comdat;2612 else2613 return NULL;2614 2564 } 2615 2565 … … 2680 2630 return FALSE; 2681 2631 } 2632 2633 /* Initialize COOKIE for input bfd ABFD. */ 2634 2635 static bfd_boolean 2636 init_reloc_cookie (struct coff_reloc_cookie *cookie, 2637 struct bfd_link_info *info ATTRIBUTE_UNUSED, 2638 bfd *abfd) 2639 { 2640 /* Sometimes the symbol table does not yet have been loaded here. */ 2641 bfd_coff_slurp_symbol_table (abfd); 2642 2643 cookie->abfd = abfd; 2644 cookie->sym_hashes = obj_coff_sym_hashes (abfd); 2645 2646 cookie->symbols = obj_symbols (abfd); 2647 2648 return TRUE; 2649 } 2650 2651 /* Free the memory allocated by init_reloc_cookie, if appropriate. */ 2652 2653 static void 2654 fini_reloc_cookie (struct coff_reloc_cookie *cookie ATTRIBUTE_UNUSED, 2655 bfd *abfd ATTRIBUTE_UNUSED) 2656 { 2657 /* Nothing to do. */ 2658 } 2659 2660 /* Initialize the relocation information in COOKIE for input section SEC 2661 of input bfd ABFD. */ 2662 2663 static bfd_boolean 2664 init_reloc_cookie_rels (struct coff_reloc_cookie *cookie, 2665 struct bfd_link_info *info ATTRIBUTE_UNUSED, 2666 bfd *abfd, 2667 asection *sec) 2668 { 2669 if (sec->reloc_count == 0) 2670 { 2671 cookie->rels = NULL; 2672 cookie->relend = NULL; 2673 cookie->rel = NULL; 2674 return TRUE; 2675 } 2676 2677 cookie->rels = _bfd_coff_read_internal_relocs (abfd, sec, FALSE, NULL, 0, NULL); 2678 2679 if (cookie->rels == NULL) 2680 return FALSE; 2681 2682 cookie->rel = cookie->rels; 2683 cookie->relend = (cookie->rels + sec->reloc_count); 2684 return TRUE; 2685 } 2686 2687 /* Free the memory allocated by init_reloc_cookie_rels, 2688 if appropriate. */ 2689 2690 static void 2691 fini_reloc_cookie_rels (struct coff_reloc_cookie *cookie, 2692 asection *sec) 2693 { 2694 if (cookie->rels 2695 /* PR 20401. The relocs may not have been cached, so check first. 2696 If the relocs were loaded by init_reloc_cookie_rels() then this 2697 will be the case. FIXME: Would performance be improved if the 2698 relocs *were* cached ? */ 2699 && coff_section_data (NULL, sec) 2700 && coff_section_data (NULL, sec)->relocs != cookie->rels) 2701 free (cookie->rels); 2702 } 2703 2704 /* Initialize the whole of COOKIE for input section SEC. */ 2705 2706 static bfd_boolean 2707 init_reloc_cookie_for_section (struct coff_reloc_cookie *cookie, 2708 struct bfd_link_info *info, 2709 asection *sec) 2710 { 2711 if (!init_reloc_cookie (cookie, info, sec->owner)) 2712 return FALSE; 2713 2714 if (!init_reloc_cookie_rels (cookie, info, sec->owner, sec)) 2715 { 2716 fini_reloc_cookie (cookie, sec->owner); 2717 return FALSE; 2718 } 2719 return TRUE; 2720 } 2721 2722 /* Free the memory allocated by init_reloc_cookie_for_section, 2723 if appropriate. */ 2724 2725 static void 2726 fini_reloc_cookie_for_section (struct coff_reloc_cookie *cookie, 2727 asection *sec) 2728 { 2729 fini_reloc_cookie_rels (cookie, sec); 2730 fini_reloc_cookie (cookie, sec->owner); 2731 } 2732 2733 static asection * 2734 _bfd_coff_gc_mark_hook (asection *sec, 2735 struct bfd_link_info *info ATTRIBUTE_UNUSED, 2736 struct internal_reloc *rel ATTRIBUTE_UNUSED, 2737 struct coff_link_hash_entry *h, 2738 struct internal_syment *sym) 2739 { 2740 if (h != NULL) 2741 { 2742 switch (h->root.type) 2743 { 2744 case bfd_link_hash_defined: 2745 case bfd_link_hash_defweak: 2746 return h->root.u.def.section; 2747 2748 case bfd_link_hash_common: 2749 return h->root.u.c.p->section; 2750 2751 case bfd_link_hash_undefined: 2752 case bfd_link_hash_undefweak: 2753 default: 2754 break; 2755 } 2756 return NULL; 2757 } 2758 2759 return coff_section_from_bfd_index (sec->owner, sym->n_scnum); 2760 } 2761 2762 /* COOKIE->rel describes a relocation against section SEC, which is 2763 a section we've decided to keep. Return the section that contains 2764 the relocation symbol, or NULL if no section contains it. */ 2765 2766 static asection * 2767 _bfd_coff_gc_mark_rsec (struct bfd_link_info *info, asection *sec, 2768 coff_gc_mark_hook_fn gc_mark_hook, 2769 struct coff_reloc_cookie *cookie) 2770 { 2771 struct coff_link_hash_entry *h; 2772 2773 h = cookie->sym_hashes[cookie->rel->r_symndx]; 2774 if (h != NULL) 2775 { 2776 while (h->root.type == bfd_link_hash_indirect 2777 || h->root.type == bfd_link_hash_warning) 2778 h = (struct coff_link_hash_entry *) h->root.u.i.link; 2779 2780 return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL); 2781 } 2782 2783 return (*gc_mark_hook) (sec, info, cookie->rel, NULL, 2784 &(cookie->symbols 2785 + obj_convert (sec->owner)[cookie->rel->r_symndx])->native->u.syment); 2786 } 2787 2788 static bfd_boolean _bfd_coff_gc_mark 2789 (struct bfd_link_info *, asection *, coff_gc_mark_hook_fn); 2790 2791 /* COOKIE->rel describes a relocation against section SEC, which is 2792 a section we've decided to keep. Mark the section that contains 2793 the relocation symbol. */ 2794 2795 static bfd_boolean 2796 _bfd_coff_gc_mark_reloc (struct bfd_link_info *info, 2797 asection *sec, 2798 coff_gc_mark_hook_fn gc_mark_hook, 2799 struct coff_reloc_cookie *cookie) 2800 { 2801 asection *rsec; 2802 2803 rsec = _bfd_coff_gc_mark_rsec (info, sec, gc_mark_hook, cookie); 2804 if (rsec && !rsec->gc_mark) 2805 { 2806 if (bfd_get_flavour (rsec->owner) != bfd_target_coff_flavour) 2807 rsec->gc_mark = 1; 2808 else if (!_bfd_coff_gc_mark (info, rsec, gc_mark_hook)) 2809 return FALSE; 2810 } 2811 return TRUE; 2812 } 2813 2814 /* The mark phase of garbage collection. For a given section, mark 2815 it and any sections in this section's group, and all the sections 2816 which define symbols to which it refers. */ 2817 2818 static bfd_boolean 2819 _bfd_coff_gc_mark (struct bfd_link_info *info, 2820 asection *sec, 2821 coff_gc_mark_hook_fn gc_mark_hook) 2822 { 2823 bfd_boolean ret = TRUE; 2824 2825 sec->gc_mark = 1; 2826 2827 /* Look through the section relocs. */ 2828 if ((sec->flags & SEC_RELOC) != 0 2829 && sec->reloc_count > 0) 2830 { 2831 struct coff_reloc_cookie cookie; 2832 2833 if (!init_reloc_cookie_for_section (&cookie, info, sec)) 2834 ret = FALSE; 2835 else 2836 { 2837 for (; cookie.rel < cookie.relend; cookie.rel++) 2838 { 2839 if (!_bfd_coff_gc_mark_reloc (info, sec, gc_mark_hook, &cookie)) 2840 { 2841 ret = FALSE; 2842 break; 2843 } 2844 } 2845 fini_reloc_cookie_for_section (&cookie, sec); 2846 } 2847 } 2848 2849 return ret; 2850 } 2851 2852 static bfd_boolean 2853 _bfd_coff_gc_mark_extra_sections (struct bfd_link_info *info, 2854 coff_gc_mark_hook_fn mark_hook ATTRIBUTE_UNUSED) 2855 { 2856 bfd *ibfd; 2857 2858 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next) 2859 { 2860 asection *isec; 2861 bfd_boolean some_kept; 2862 2863 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour) 2864 continue; 2865 2866 /* Ensure all linker created sections are kept, and see whether 2867 any other section is already marked. */ 2868 some_kept = FALSE; 2869 for (isec = ibfd->sections; isec != NULL; isec = isec->next) 2870 { 2871 if ((isec->flags & SEC_LINKER_CREATED) != 0) 2872 isec->gc_mark = 1; 2873 else if (isec->gc_mark) 2874 some_kept = TRUE; 2875 } 2876 2877 /* If no section in this file will be kept, then we can 2878 toss out debug sections. */ 2879 if (!some_kept) 2880 continue; 2881 2882 /* Keep debug and special sections like .comment when they are 2883 not part of a group, or when we have single-member groups. */ 2884 for (isec = ibfd->sections; isec != NULL; isec = isec->next) 2885 if ((isec->flags & SEC_DEBUGGING) != 0 2886 || (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) 2887 isec->gc_mark = 1; 2888 } 2889 return TRUE; 2890 } 2891 2892 /* Sweep symbols in swept sections. Called via coff_link_hash_traverse. */ 2893 2894 static bfd_boolean 2895 coff_gc_sweep_symbol (struct coff_link_hash_entry *h, 2896 void *data ATTRIBUTE_UNUSED) 2897 { 2898 if (h->root.type == bfd_link_hash_warning) 2899 h = (struct coff_link_hash_entry *) h->root.u.i.link; 2900 2901 if ((h->root.type == bfd_link_hash_defined 2902 || h->root.type == bfd_link_hash_defweak) 2903 && !h->root.u.def.section->gc_mark 2904 && !(h->root.u.def.section->owner->flags & DYNAMIC)) 2905 { 2906 /* Do our best to hide the symbol. */ 2907 h->root.u.def.section = bfd_und_section_ptr; 2908 h->symbol_class = C_HIDDEN; 2909 } 2910 2911 return TRUE; 2912 } 2913 2914 /* The sweep phase of garbage collection. Remove all garbage sections. */ 2915 2916 typedef bfd_boolean (*gc_sweep_hook_fn) 2917 (bfd *, struct bfd_link_info *, asection *, const struct internal_reloc *); 2918 2919 static bfd_boolean 2920 coff_gc_sweep (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) 2921 { 2922 bfd *sub; 2923 2924 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) 2925 { 2926 asection *o; 2927 2928 if (bfd_get_flavour (sub) != bfd_target_coff_flavour) 2929 continue; 2930 2931 for (o = sub->sections; o != NULL; o = o->next) 2932 { 2933 /* Keep debug and special sections. */ 2934 if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 2935 || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) 2936 o->gc_mark = 1; 2937 else if (CONST_STRNEQ (o->name, ".idata") 2938 || CONST_STRNEQ (o->name, ".pdata") 2939 || CONST_STRNEQ (o->name, ".xdata") 2940 || CONST_STRNEQ (o->name, ".rsrc")) 2941 o->gc_mark = 1; 2942 2943 if (o->gc_mark) 2944 continue; 2945 2946 /* Skip sweeping sections already excluded. */ 2947 if (o->flags & SEC_EXCLUDE) 2948 continue; 2949 2950 /* Since this is early in the link process, it is simple 2951 to remove a section from the output. */ 2952 o->flags |= SEC_EXCLUDE; 2953 2954 if (info->print_gc_sections && o->size != 0) 2955 _bfd_error_handler (_("Removing unused section '%s' in file '%B'"), sub, o->name); 2956 2957 #if 0 2958 /* But we also have to update some of the relocation 2959 info we collected before. */ 2960 if (gc_sweep_hook 2961 && (o->flags & SEC_RELOC) != 0 2962 && o->reloc_count > 0 2963 && !bfd_is_abs_section (o->output_section)) 2964 { 2965 struct internal_reloc *internal_relocs; 2966 bfd_boolean r; 2967 2968 internal_relocs 2969 = _bfd_coff_link_read_relocs (o->owner, o, NULL, NULL, 2970 info->keep_memory); 2971 if (internal_relocs == NULL) 2972 return FALSE; 2973 2974 r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); 2975 2976 if (coff_section_data (o)->relocs != internal_relocs) 2977 free (internal_relocs); 2978 2979 if (!r) 2980 return FALSE; 2981 } 2982 #endif 2983 } 2984 } 2985 2986 /* Remove the symbols that were in the swept sections from the dynamic 2987 symbol table. */ 2988 coff_link_hash_traverse (coff_hash_table (info), coff_gc_sweep_symbol, 2989 NULL); 2990 2991 return TRUE; 2992 } 2993 2994 /* Keep all sections containing symbols undefined on the command-line, 2995 and the section containing the entry symbol. */ 2996 2997 static void 2998 _bfd_coff_gc_keep (struct bfd_link_info *info) 2999 { 3000 struct bfd_sym_chain *sym; 3001 3002 for (sym = info->gc_sym_list; sym != NULL; sym = sym->next) 3003 { 3004 struct coff_link_hash_entry *h; 3005 3006 h = coff_link_hash_lookup (coff_hash_table (info), sym->name, 3007 FALSE, FALSE, FALSE); 3008 3009 if (h != NULL 3010 && (h->root.type == bfd_link_hash_defined 3011 || h->root.type == bfd_link_hash_defweak) 3012 && !bfd_is_abs_section (h->root.u.def.section)) 3013 h->root.u.def.section->flags |= SEC_KEEP; 3014 } 3015 } 3016 3017 /* Do mark and sweep of unused sections. */ 3018 3019 bfd_boolean 3020 bfd_coff_gc_sections (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) 3021 { 3022 bfd *sub; 3023 3024 /* FIXME: Should we implement this? */ 3025 #if 0 3026 const bfd_coff_backend_data *bed = coff_backend_info (abfd); 3027 3028 if (!bed->can_gc_sections 3029 || !is_coff_hash_table (info->hash)) 3030 { 3031 (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); 3032 return TRUE; 3033 } 3034 #endif 3035 3036 _bfd_coff_gc_keep (info); 3037 3038 /* Grovel through relocs to find out who stays ... */ 3039 for (sub = info->input_bfds; sub != NULL; sub = sub->link.next) 3040 { 3041 asection *o; 3042 3043 if (bfd_get_flavour (sub) != bfd_target_coff_flavour) 3044 continue; 3045 3046 for (o = sub->sections; o != NULL; o = o->next) 3047 { 3048 if (((o->flags & (SEC_EXCLUDE | SEC_KEEP)) == SEC_KEEP 3049 || CONST_STRNEQ (o->name, ".vectors") 3050 || CONST_STRNEQ (o->name, ".ctors") 3051 || CONST_STRNEQ (o->name, ".dtors")) 3052 && !o->gc_mark) 3053 { 3054 if (!_bfd_coff_gc_mark (info, o, _bfd_coff_gc_mark_hook)) 3055 return FALSE; 3056 } 3057 } 3058 } 3059 3060 /* Allow the backend to mark additional target specific sections. */ 3061 _bfd_coff_gc_mark_extra_sections (info, _bfd_coff_gc_mark_hook); 3062 3063 /* ... and mark SEC_EXCLUDE for those that go. */ 3064 return coff_gc_sweep (abfd, info); 3065 }
Note:
See TracChangeset
for help on using the changeset viewer.