s/struct _serial_t/struct serial/
[deliverable/binutils-gdb.git] / bfd / cofflink.c
index 8c825968dd56ab8345db866b6d07ee443fac30a8..47716ac2eaea8b0fcbacd6fb42568d57b8a98a02 100644 (file)
@@ -1,5 +1,6 @@
 /* COFF specific linker code.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -928,7 +929,7 @@ _bfd_coff_final_link (abfd, info)
 
   if (! bfd_coff_final_link_postscript (abfd, & finfo))
     goto error_return;
-  
+
   /* Free up the buffers used by _bfd_coff_link_input_bfd.  */
 
   coff_debug_merge_hash_table_free (&finfo.debug_merge);
@@ -989,7 +990,7 @@ _bfd_coff_final_link (abfd, info)
 
   /* If doing task linking (ld --task-link) then make a pass through the
      global symbols, writing out any that are defined, and making them
-     static. */
+     static.  */
   if (info->task_link)
     {
       finfo.failed = false;
@@ -1102,6 +1103,8 @@ _bfd_coff_final_link (abfd, info)
 
       if (! _bfd_stringtab_emit (abfd, finfo.strtab))
        return false;
+
+      obj_coff_strings_written (abfd) = true;
     }
 
   _bfd_stringtab_free (finfo.strtab);
@@ -1159,7 +1162,7 @@ dores_com (ptr, output_bfd, heap)
      bfd *output_bfd;
      int heap;
 {
-  if (coff_data(output_bfd)->pe) 
+  if (coff_data(output_bfd)->pe)
     {
       int val = strtoul (ptr, &ptr, 0);
       if (heap)
@@ -1167,7 +1170,7 @@ dores_com (ptr, output_bfd, heap)
       else
        pe_data(output_bfd)->pe_opthdr.SizeOfStackReserve =val;
 
-      if (ptr[0] == ',') 
+      if (ptr[0] == ',')
        {
          int val = strtoul (ptr+1, &ptr, 0);
          if (heap)
@@ -1193,7 +1196,7 @@ char **dst;
 }
 
 /* Process any magic embedded commands in a section called .drectve */
-                       
+
 static int
 process_embedded_commands (output_bfd, info,  abfd)
      bfd *output_bfd;
@@ -1204,19 +1207,19 @@ process_embedded_commands (output_bfd, info,  abfd)
   char *s;
   char *e;
   char *copy;
-  if (!sec) 
+  if (!sec)
     return 1;
-  
+
   copy = bfd_malloc ((size_t) sec->_raw_size);
-  if (!copy) 
+  if (!copy)
     return 0;
-  if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size)) 
+  if (! bfd_get_section_contents(abfd, sec, copy, 0, sec->_raw_size))
     {
       free (copy);
       return 0;
     }
   e = copy + sec->_raw_size;
-  for (s = copy;  s < e ; ) 
+  for (s = copy;  s < e ; )
     {
       if (s[0]!= '-') {
        s++;
@@ -1237,7 +1240,7 @@ process_embedded_commands (output_bfd, info,  abfd)
          s = get_name(s, &name);
          s = get_name(s, &attribs);
          while (loop) {
-           switch (*attribs++) 
+           switch (*attribs++)
              {
              case 'W':
                had_write = 1;
@@ -1271,7 +1274,7 @@ process_embedded_commands (output_bfd, info,  abfd)
        {
          s = dores_com (s+6, output_bfd, 0);
        }
-      else 
+      else
        s++;
     }
   free (copy);
@@ -1281,7 +1284,7 @@ process_embedded_commands (output_bfd, info,  abfd)
 /* Place a marker against all symbols which are used by relocations.
    This marker can be picked up by the 'do we skip this symbol ?'
    loop in _bfd_coff_link_input_bfd() and used to prevent skipping
-   that symbol. 
+   that symbol.
    */
 
 static void
@@ -1293,14 +1296,13 @@ mark_relocs (finfo, input_bfd)
 
   if ((bfd_get_file_flags (input_bfd) & HAS_SYMS) == 0)
     return;
-  
+
   for (a = input_bfd->sections; a != (asection *) NULL; a = a->next)
     {
       struct internal_reloc *  internal_relocs;
       struct internal_reloc *  irel;
       struct internal_reloc *  irelend;
 
-      
       if ((a->flags & SEC_RELOC) == 0 || a->reloc_count  < 1)
        continue;
 
@@ -1313,7 +1315,7 @@ mark_relocs (finfo, input_bfd)
          ? (finfo->section_info[ a->output_section->target_index ].relocs + a->output_section->reloc_count)
          : finfo->internal_relocs)
        );
-      
+
       if (internal_relocs == NULL)
        continue;
 
@@ -1324,7 +1326,7 @@ mark_relocs (finfo, input_bfd)
         been initialised to 0) for all of the symbols that are used
         in the relocation table.  This will then be picked up in the
         skip/don't pass */
-      
+
       for (; irel < irelend; irel++)
        {
          finfo->sym_indices[ irel->r_symndx ] = -1;
@@ -1407,8 +1409,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       && finfo->info->relocateable)
     {
       /* mark the symbol array as 'not-used' */
-      memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp); 
-       
+      memset (indexp, 0, obj_raw_syment_count (input_bfd) * sizeof * indexp);
+
       mark_relocs (finfo, input_bfd);
     }
 
@@ -1455,7 +1457,7 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
        dont_skip_symbol = *indexp;
       else
        dont_skip_symbol = false;
-      
+
       *indexp = -1;
 
       skip = false;
@@ -1499,6 +1501,21 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
            }
        }
 
+#ifndef COFF_WITH_PE
+      /* Skip section symbols for sections which are not going to be
+        emitted, or which belong to linkonce sections that are going
+        to be discarded.  */
+      if (!skip
+         && isym.n_sclass == C_STAT
+         && isym.n_type == T_NULL
+          && isym.n_numaux > 0)
+        {
+          if ((*secpp)->output_section == bfd_abs_section_ptr
+              || (*secpp)->kept_section)
+            skip = true;
+        }
+#endif
+
       /* If we stripping debugging symbols, and this is a debugging
          symbol, then skip it.  FIXME: gas sets the section to N_ABS
          for some types of debugging symbols; I don't know if this is
@@ -2403,8 +2420,8 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
                          /* This reloc is against a symbol we are
                              stripping.  This should have been handled
                             by the 'dont_skip_symbol' code in the while
-                            loop at the top of this function. */
-                         
+                            loop at the top of this function.  */
+
                          is = finfo->internal_syms + irel->r_symndx;
 
                          name = (_bfd_coff_internal_syment_name
@@ -2428,9 +2445,9 @@ _bfd_coff_link_input_bfd (finfo, input_bfd)
       if (secdata == NULL || secdata->stab_info == NULL)
        {
          if (! bfd_set_section_contents (output_bfd, o->output_section,
-                                         contents, 
-                                          (file_ptr) 
-                                          (o->output_offset * 
+                                         contents,
+                                          (file_ptr)
+                                          (o->output_offset *
                                            bfd_octets_per_byte (output_bfd)),
                                          (o->_cooked_size != 0
                                           ? o->_cooked_size
@@ -2570,7 +2587,7 @@ _bfd_coff_write_global_sym (h, data)
     isym.n_sclass = C_EXT;
 
   isym.n_numaux = h->numaux;
-  
+
   bfd_coff_swap_sym_out (output_bfd, (PTR) &isym, (PTR) finfo->outsyms);
 
   symesz = bfd_coff_symesz (output_bfd);
@@ -2662,7 +2679,7 @@ _bfd_coff_write_global_sym (h, data)
 
 /* Write out task global symbols, converting them to statics.  Called
    via coff_link_hash_traverse.  Calls bfd_coff_write_global_sym to do
-   the dirty work, if the symbol we are processing needs conversion. */
+   the dirty work, if the symbol we are processing needs conversion.  */
 
 boolean
 _bfd_coff_write_task_globals (h, data)
@@ -2748,7 +2765,7 @@ _bfd_coff_reloc_link_order (output_bfd, finfo, output_section, link_order)
          break;
        }
       ok = bfd_set_section_contents (output_bfd, output_section, (PTR) buf,
-                                    (file_ptr) 
+                                    (file_ptr)
                                      (link_order->offset *
                                       bfd_octets_per_byte (output_bfd)), size);
       free (buf);
@@ -2870,7 +2887,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
          return false;
        }
       else
-       {    
+       {
          h = obj_coff_sym_hashes (input_bfd)[symndx];
          sym = syms + symndx;
        }
@@ -2885,7 +2902,6 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
       else
        addend = 0;
 
-
       howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
                                       sym, &addend);
       if (howto == NULL)
@@ -2937,6 +2953,9 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
                     + sec->output_offset);
              }
 
+         else if (h->root.type == bfd_link_hash_undefweak)
+           val = 0;
+
          else if (! info->relocateable)
            {
              if (! ((*info->callbacks->undefined_symbol)
@@ -2948,7 +2967,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
 
       if (info->base_file)
        {
-         /* Emit a reloc if the backend thinks it needs it. */
+         /* Emit a reloc if the backend thinks it needs it.  */
          if (sym && pe_data (output_bfd)->in_reloc_p (output_bfd, howto))
            {
              /* Relocation to a symbol in a section which isn't
@@ -2957,9 +2976,9 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
                 reloc section.  Note that the base file is not
                 portable between systems.  We write out a long here,
                 and dlltool reads in a long.  */
-             long addr = (rel->r_vaddr 
-                          - input_section->vma 
-                          + input_section->output_offset 
+             long addr = (rel->r_vaddr
+                          - input_section->vma
+                          + input_section->output_offset
                           + input_section->output_section->vma);
              if (coff_data (output_bfd)->pe)
                addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
@@ -2971,7 +2990,7 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
                }
            }
        }
-  
+
       rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                        contents,
                                        rel->r_vaddr - input_section->vma,
@@ -3015,4 +3034,3 @@ _bfd_coff_generic_relocate_section (output_bfd, info, input_bfd,
     }
   return true;
 }
-
This page took 0.027267 seconds and 4 git commands to generate.