Ignore:
Timestamp:
Feb 6, 2017, 1:00:00 PM (8 years ago)
Author:
Silvan Scherrer
Message:

binutils: update trunk to version 2.27

Location:
binutils/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • binutils/trunk

  • TabularUnified binutils/trunk/bfd/coffgen.c

    r970 r1973  
    11/* Support for the generic parts of COFF, for BFD.
    2    Copyright (C) 1990-2014 Free Software Foundation, Inc.
     2   Copyright (C) 1990-2016 Free Software Foundation, Inc.
    33   Written by Cygnus Support.
    44
     
    147147     .zdebug_*, after the section flags is set.  */
    148148  if ((flags & SEC_DEBUGGING)
     149      && strlen (name) > 7
    149150      && ((name[1] == 'd' && name[6] == '_')
    150           || (name[1] == 'z' && name[7] == '_')))
     151          || (strlen (name) > 8 && name[1] == 'z' && name[7] == '_')))
    151152    {
    152153      enum { nothing, compress, decompress } action = nothing;
     
    178179              return FALSE;
    179180            }
    180           if (name[1] != 'z')
     181          if (return_section->compress_status == COMPRESS_SECTION_DONE)
    181182            {
    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                }
    190194            }
    191           break;
     195         break;
    192196        case decompress:
    193197          if (!bfd_init_section_decompress_status (abfd, return_section))
     
    366370          return NULL;
    367371        }
     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
    368376      bfd_coff_swap_aouthdr_in (abfd, opthdr, (void *) &internal_a);
    369377      bfd_release (abfd, opthdr);
     
    464472            return NULL;
    465473        }
    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))
    467478        return NULL;
    468479      return strings + sym->_n._n_n._n_offset;
     
    627638
    628639  return total;
    629 }
    630 
    631 /* Takes a bfd and a symbol, returns a pointer to the coff specific
    632    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;
    645640}
    646641
     
    761756  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
    762757    {
    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]);
    765761      symbol_ptr_ptr[symbol_index]->udata.i = symbol_index;
    766762      if (coff_symbol_ptr && coff_symbol_ptr->native)
     
    806802  for (symbol_index = 0; symbol_index < symbol_count; symbol_index++)
    807803    {
    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]);
    811807      if (coff_symbol_ptr && coff_symbol_ptr->native)
    812808        {
     
    10711067                         asymbol *symbol,
    10721068                         struct internal_syment *isym,
     1069                         union internal_auxent *iaux,
    10731070                         bfd_vma *written,
    10741071                         bfd_size_type *string_size_p,
     
    11361133         FIXME: Why?  */
    11371134      {
    1138         coff_symbol_type *c = coff_symbol_from (abfd, symbol);
     1135        coff_symbol_type *c = coff_symbol_from (symbol);
    11391136        if (c != (coff_symbol_type *) NULL)
    11401137          native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
     
    11561153  if (isym != NULL)
    11571154    *isym = native->u.syment;
     1155  if (iaux != NULL && native->u.syment.n_numaux)
     1156    *iaux = native[1].u.auxent;
    11581157  return ret;
    11591158}
     
    12681267    {
    12691268      asymbol *symbol = *p;
    1270       coff_symbol_type *c_symbol = coff_symbol_from (abfd, symbol);
     1269      coff_symbol_type *c_symbol = coff_symbol_from (symbol);
    12711270
    12721271      if (c_symbol == (coff_symbol_type *) NULL
    12731272          || c_symbol->native == (combined_entry_type *) NULL)
    12741273        {
    1275           if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
     1274          if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written,
    12761275                                        &string_size, &debug_string_section,
    12771276                                        &debug_string_size))
     
    13681367          asymbol *q = *p;
    13691368          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);
    13711370          size_t maxlen;
    13721371
     
    13861385          else if (! c_symbol->native->is_sym)
    13871386            maxlen = bfd_coff_force_symnames_in_strings (abfd) ? 0 : SYMNMLEN;
    1388            
     1387
    13891388          else if (bfd_coff_symname_in_debug (abfd,
    13901389                                              &c_symbol->native->u.syment))
     
    17121711
    17131712  strings = (char *) bfd_malloc (strsize + 1);
     1713  if (strings == NULL)
     1714    return NULL;
     1715
    17141716  /* PR 17521 file: 079-54929-0.004.
    17151717     A corrupt file could contain an index that points into the first
     
    17171719     they are zero.  */
    17181720  memset (strings, 0, STRING_SIZE_SIZE);
    1719 
    1720   if (strings == NULL)
    1721     return NULL;
    17221721
    17231722  if (bfd_bread (strings + STRING_SIZE_SIZE, strsize - STRING_SIZE_SIZE, abfd)
     
    17871786    return NULL;
    17881787  internal_end = internal + obj_raw_syment_count (abfd);
    1789  
     1788
    17901789  raw_src = (char *) obj_coff_external_syms (abfd);
    17911790
     
    18091808      internal_ptr->is_sym = TRUE;
    18101809
     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
    18111820      for (i = 0;
    18121821           i < symbol_ptr->u.syment.n_numaux;
     
    18161825          /* PR 17512: Prevent buffer overrun.  */
    18171826          if (internal_ptr >= internal_end)
    1818             return NULL;
     1827            {
     1828              bfd_release (abfd, internal);
     1829              return NULL;
     1830            }
    18191831
    18201832          raw_src += symesz;
     
    18241836                                (int) i, symbol_ptr->u.syment.n_numaux,
    18251837                                &(internal_ptr->u.auxent));
     1838
    18261839          internal_ptr->is_sym = FALSE;
    18271840          coff_pointerize_aux (abfd, internal, symbol_ptr, i,
     
    20262039}
    20272040
    2028 /* Return the COFF syment for a symbol.  */
    2029 
    2030 bfd_boolean
    2031 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 == NULL
    2039       || ! 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_boolean
    2059 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 == NULL
    2070       || csym->native == NULL
    2071       || ! csym->native->is_sym
    2072       || 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.p
    2086        - 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.p
    2091        - 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.p
    2096        - obj_raw_syments (abfd));
    2097 
    2098   return TRUE;
    2099 }
    2100 
    21012041/* Print out information about COFF symbol.  */
    21022042
     
    23112251    return TRUE;
    23122252
     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
    23132273  *filename_ptr = 0;
    23142274  *functionname_ptr = 0;
     
    25302490  size_t size;
    25312491
    2532   if (!info->relocatable)
     2492  if (!bfd_link_relocatable (info))
    25332493    size = bfd_coff_filhsz (abfd) + bfd_coff_aoutsz (abfd);
    25342494  else
     
    25482508  coff_symbol_type * csym;
    25492509
    2550   csym = coff_symbol_from (abfd, symbol);
     2510  csym = coff_symbol_from (symbol);
    25512511  if (csym == NULL)
    25522512    {
     
    26022562
    26032563  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_flavour
    2610       && coff_section_data (abfd, sec) != NULL)
    2611     return coff_section_data (abfd, sec)->comdat;
    2612   else
    2613     return NULL;
    26142564}
    26152565
     
    26802630  return FALSE;
    26812631}
     2632
     2633/* Initialize COOKIE for input bfd ABFD. */
     2634
     2635static bfd_boolean
     2636init_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
     2653static void
     2654fini_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
     2663static bfd_boolean
     2664init_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
     2690static void
     2691fini_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
     2706static bfd_boolean
     2707init_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
     2725static void
     2726fini_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
     2733static 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
     2766static 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
     2788static 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
     2795static 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
     2818static 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
     2852static 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
     2894static bfd_boolean
     2895coff_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
     2916typedef bfd_boolean (*gc_sweep_hook_fn)
     2917  (bfd *, struct bfd_link_info *, asection *, const struct internal_reloc *);
     2918
     2919static bfd_boolean
     2920coff_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
     2997static 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
     3019bfd_boolean
     3020bfd_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.