* config/tc-mips.c (mips_dwarf2_addr_size): Use HAVE_64BIT_OBJECTS
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index f4f97b3f0d798f853a6a9b61cb7e7bd4057e068c..0faaede68fd7a27c10433c04046f44bcc9a04f6d 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for the generic parts of COFF, for BFD.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -59,8 +59,13 @@ make_a_section_from_file (bfd *abfd,
 
   name = NULL;
 
-  /* Handle long section names as in PE.  */
-  if (bfd_coff_long_section_names (abfd)
+  /* Handle long section names as in PE.  On reading, we want to
+    accept long names if the format permits them at all, regardless
+    of the current state of the flag that dictates if we would generate
+    them in outputs; this construct checks if that is the case by
+    attempting to set the flag, without changing its state; the call
+    will fail for formats that do not support long names at all.  */
+  if (bfd_coff_set_long_section_names (abfd, bfd_coff_long_section_names (abfd))
       && hdr->s_name[0] == '/')
     {
       char buf[SCNNMLEN];
@@ -409,6 +414,9 @@ _bfd_coff_read_internal_relocs (bfd *abfd,
   struct internal_reloc *irel;
   bfd_size_type amt;
 
+  if (sec->reloc_count == 0)
+    return internal_relocs;    /* Nothing to do.  */
+
   if (coff_section_data (abfd, sec) != NULL
       && coff_section_data (abfd, sec)->relocs != NULL)
     {
@@ -425,7 +433,7 @@ _bfd_coff_read_internal_relocs (bfd *abfd,
   if (external_relocs == NULL)
     {
       free_external = bfd_malloc (amt);
-      if (free_external == NULL && sec->reloc_count > 0)
+      if (free_external == NULL)
        goto error_return;
       external_relocs = free_external;
     }
@@ -439,7 +447,7 @@ _bfd_coff_read_internal_relocs (bfd *abfd,
       amt = sec->reloc_count;
       amt *= sizeof (struct internal_reloc);
       free_internal = bfd_malloc (amt);
-      if (free_internal == NULL && sec->reloc_count > 0)
+      if (free_internal == NULL)
        goto error_return;
       internal_relocs = free_internal;
     }
@@ -562,7 +570,8 @@ fixup_symbol_value (bfd *abfd,
                    struct internal_syment *syment)
 {
   /* Normalize the symbol flags.  */
-  if (bfd_is_com_section (coff_symbol_ptr->symbol.section))
+  if (coff_symbol_ptr->symbol.section 
+      && bfd_is_com_section (coff_symbol_ptr->symbol.section))
     {
       /* A common symbol is undefined with a value.  */
       syment->n_scnum = N_UNDEF;
@@ -1078,6 +1087,11 @@ coff_write_native_symbol (bfd *abfd,
                            debug_string_size_p);
 }
 
+static void
+null_error_handler (const char * fmt ATTRIBUTE_UNUSED, ...)
+{
+}
+
 /* Write out the COFF symbols.  */
 
 bfd_boolean
@@ -1134,6 +1148,42 @@ coff_write_symbols (bfd *abfd)
        }
       else
        {
+         if (coff_backend_info (abfd)->_bfd_coff_classify_symbol != NULL)
+           {
+             bfd_error_handler_type current_error_handler;
+             enum coff_symbol_classification class;
+             unsigned char *n_sclass;
+
+             /* Suppress error reporting by bfd_coff_classify_symbol.
+                Error messages can be generated when we are processing a local
+                symbol which has no associated section and we do not have to
+                worry about this, all we need to know is that it is local.  */
+             current_error_handler = bfd_set_error_handler (null_error_handler);
+             class = bfd_coff_classify_symbol (abfd, &c_symbol->native->u.syment);
+             (void) bfd_set_error_handler (current_error_handler);
+         
+             n_sclass = &c_symbol->native->u.syment.n_sclass;
+
+             /* If the symbol class has been changed (eg objcopy/ld script/etc)
+                we cannot retain the existing sclass from the original symbol.
+                Weak symbols only have one valid sclass, so just set it always.
+                If it is not local class and should be, set it C_STAT.
+                If it is global and not classified as global, or if it is
+                weak (which is also classified as global), set it C_EXT.  */
+
+             if (symbol->flags & BSF_WEAK)
+               *n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
+             else if (symbol->flags & BSF_LOCAL && class != COFF_SYMBOL_LOCAL)
+               *n_sclass = C_STAT;
+             else if (symbol->flags & BSF_GLOBAL
+                      && (class != COFF_SYMBOL_GLOBAL
+#ifdef COFF_WITH_PE
+                          || *n_sclass == C_NT_WEAK
+#endif
+                          || *n_sclass == C_WEAKEXT))
+               c_symbol->native->u.syment.n_sclass = C_EXT;
+           }
+
          if (!coff_write_native_symbol (abfd, c_symbol, &written,
                                         &string_size, &debug_string_section,
                                         &debug_string_size))
@@ -1689,7 +1739,7 @@ coff_get_normalized_symtab (bfd *abfd)
              internal_ptr->u.syment._n._n_n._n_zeroes = 0;
            }
          else if (internal_ptr->u.syment._n._n_n._n_offset == 0)
-           internal_ptr->u.syment._n._n_n._n_offset = (bfd_vma) "";
+           internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) "";
          else if (!bfd_coff_symname_in_debug (abfd, &internal_ptr->u.syment))
            {
              /* Long name already.  Point symbol at the string in the
@@ -1942,7 +1992,7 @@ coff_print_symbol (bfd *abfd,
                    /* Probably a section symbol ?  */
                    {
                      fprintf (file, "AUX scnlen 0x%lx nreloc %d nlnno %d",
-                              (long) auxp->u.auxent.x_scn.x_scnlen,
+                              (unsigned long) auxp->u.auxent.x_scn.x_scnlen,
                               auxp->u.auxent.x_scn.x_nreloc,
                               auxp->u.auxent.x_scn.x_nlinno);
                      if (auxp->u.auxent.x_scn.x_checksum != 0
@@ -1956,6 +2006,7 @@ coff_print_symbol (bfd *abfd,
                    }
                    /* Otherwise fall through.  */
                case C_EXT:
+               case C_AIX_WEAKEXT:
                  if (ISFCN (combined->u.syment.n_type))
                    {
                      long next, llnos;
@@ -1968,7 +2019,8 @@ coff_print_symbol (bfd *abfd,
                      llnos = auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr;
                      fprintf (file,
                               "AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld",
-                              tagndx, auxp->u.auxent.x_sym.x_misc.x_fsize,
+                              tagndx,
+                              (unsigned long) auxp->u.auxent.x_sym.x_misc.x_fsize,
                               llnos, next);
                      break;
                    }
@@ -2140,7 +2192,7 @@ coff_find_nearest_line (bfd *abfd,
     }
 
   /* Now wander though the raw linenumbers of the section.  */
-  /* If we have been called on this section before, and the offset we
+  /* If we have been called on this section before, and the offset we
      want is further down then we can prime the lookup loop.  */
   sec_data = coff_section_data (abfd, section);
   if (sec_data != NULL
@@ -2227,7 +2279,7 @@ coff_find_nearest_line (bfd *abfd,
   if (sec_data != NULL)
     {
       sec_data->offset = offset;
-      sec_data->i = i;
+      sec_data->i = i - 1;
       sec_data->function = *functionname_ptr;
       sec_data->line_base = line_base;
     }
This page took 0.026524 seconds and 4 git commands to generate.