* po/fi.po: Updated Finnish translation.
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index 17d46a2d5b8fa1e4ba4d67798edac3bec6a12443..a52f75a75786a6da4f57144e00dfbba77ac55a4b 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, 2008
+   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];
@@ -68,6 +73,11 @@ make_a_section_from_file (bfd *abfd,
       char *p;
       const char *strings;
 
+      /* Flag that this BFD uses long names, even though the format might
+         expect them to be off by default.  This won't directly affect the
+         format of any output BFD created from this one, but the information
+         can be used to decide what to do.  */
+      bfd_coff_set_long_section_names (abfd, TRUE);
       memcpy (buf, hdr->s_name + 1, SCNNMLEN - 1);
       buf[SCNNMLEN - 1] = '\0';
       strindex = strtol (buf, &p, 10);
@@ -1082,6 +1092,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
@@ -1138,6 +1153,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))
@@ -1908,16 +1959,7 @@ coff_print_symbol (bfd *abfd,
                   combined->u.syment.n_type,
                   combined->u.syment.n_sclass,
                   combined->u.syment.n_numaux);
-#ifdef BFD64
-         /* fprintf_vma() on a 64-bit enabled host will always print a 64-bit
-            value, but really we want to display the address in the target's
-            address size.  Since we do not have a field in the bfd structure
-            to tell us this, we take a guess, based on the target's name.  */
-         if (strstr (bfd_get_target (abfd), "64") == NULL)
-           fprintf (file, "%08lx", (unsigned long) (val & 0xffffffff));
-         else
-#endif
-           fprintf_vma (file, val);
+         bfd_fprintf_vma (abfd, file, val);
          fprintf (file, " %s", symbol->name);
 
          for (aux = 0; aux < combined->u.syment.n_numaux; aux++)
@@ -1960,6 +2002,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;
@@ -1999,7 +2042,7 @@ coff_print_symbol (bfd *abfd,
              while (l->line_number)
                {
                  fprintf (file, "\n%4d : ", l->line_number);
-                 fprintf_vma (file, l->u.offset + symbol->section->vma);
+                 bfd_fprintf_vma (abfd, file, l->u.offset + symbol->section->vma);
                  l++;
                }
            }
This page took 0.024882 seconds and 4 git commands to generate.