1999-09-06 Donn Terry <donn@interix.com>
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index df413833bd3c6251a537229a7df5905d8dd50ed8..53aaf4fbc510f956fe877ac93e17e8b77f82db81 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of COFF, for BFD.
-   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+   Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -559,7 +559,7 @@ coff_count_linenumbers (abfd)
 /*ARGSUSED*/
 coff_symbol_type *
 coff_symbol_from (ignore_abfd, symbol)
-     bfd *ignore_abfd;
+     bfd *ignore_abfd ATTRIBUTE_UNUSED;
      asymbol *symbol;
 {
   if (bfd_asymbol_flavour (symbol) != bfd_target_coff_flavour)
@@ -594,6 +594,7 @@ fixup_symbol_value (abfd, coff_symbol_ptr, syment)
       syment->n_scnum = N_UNDEF;
       syment->n_value = 0;
     }
+  /* FIXME: Do we need to handle the absolute section here?  */
   else
     {
       if (coff_symbol_ptr->symbol.section)
@@ -1351,7 +1352,7 @@ coff_write_linenumbers (abfd)
 /*ARGSUSED */
 alent *
 coff_get_lineno (ignore_abfd, symbol)
-     bfd *ignore_abfd;
+     bfd *ignore_abfd ATTRIBUTE_UNUSED;
      asymbol *symbol;
 {
   return coffsymbol (symbol)->lineno;
@@ -1746,10 +1747,26 @@ coff_get_normalized_symtab (abfd)
            }
          else
            {
-             /* ordinary short filename, put into memory anyway */
-             internal_ptr->u.syment._n._n_n._n_offset = (long)
-               copy_name (abfd, (internal_ptr + 1)->u.auxent.x_file.x_fname,
-                          FILNMLEN);
+             /* Ordinary short filename, put into memory anyway.  The
+                 Microsoft PE tools sometimes store a filename in
+                 multiple AUX entries.  */
+             if (internal_ptr->u.syment.n_numaux > 1
+                 && coff_data (abfd)->pe)
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset =
+                   ((long)
+                    copy_name (abfd,
+                               (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                               internal_ptr->u.syment.n_numaux * symesz));
+               }
+             else
+               {
+                 internal_ptr->u.syment._n._n_n._n_offset =
+                   ((long)
+                    copy_name (abfd,
+                               (internal_ptr + 1)->u.auxent.x_file.x_fname,
+                               FILNMLEN));
+               }
            }
        }
       else
@@ -1847,8 +1864,8 @@ coff_make_empty_symbol (abfd)
 asymbol *
 coff_bfd_make_debug_symbol (abfd, ptr, sz)
      bfd *abfd;
-     PTR ptr;
-     unsigned long sz;
+     PTR ptr ATTRIBUTE_UNUSED;
+     unsigned long sz ATTRIBUTE_UNUSED;
 {
   coff_symbol_type *new = (coff_symbol_type *) bfd_alloc (abfd, sizeof (coff_symbol_type));
   if (new == NULL)
@@ -2095,7 +2112,7 @@ coff_print_symbol (abfd, filep, symbol, how)
 
 boolean
 _bfd_coff_is_local_label_name (abfd, name)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      const char *name;
 {
   return name[0] == '.' && name[1] == 'L';
@@ -2190,9 +2207,11 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
                }
            }
 
+         /* We use <= MAXDIFF here so that if we get a zero length
+             file, we actually use the next file entry.  */
          if (p2 < pend
              && offset + sec_vma >= (bfd_vma) p2->u.syment.n_value
-             && offset + sec_vma - (bfd_vma) p2->u.syment.n_value < maxdiff)
+             && offset + sec_vma - (bfd_vma) p2->u.syment.n_value <= maxdiff)
            {
              *filename_ptr = (char *) p->u.syment._n._n_n._n_offset;
              maxdiff = offset + sec_vma - p2->u.syment.n_value;
@@ -2229,6 +2248,8 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
 
   if (section->lineno != NULL)
     {
+      bfd_vma last_value = 0;
+
       l = &section->lineno[i];
 
       for (; i < section->lineno_count; i++)
@@ -2240,6 +2261,7 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
              if (coff->symbol.value > offset)
                break;
              *functionname_ptr = coff->symbol.name;
+             last_value = coff->symbol.value;
              if (coff->native)
                {
                  combined_entry_type *s = coff->native;
@@ -2268,6 +2290,20 @@ coff_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
            }
          l++;
        }
+
+      /* If we fell off the end of the loop, then assume that this
+        symbol has no line number info.  Otherwise, symbols with no
+        line number info get reported with the line number of the
+        last line of the last symbol which does have line number
+        info.  We use 0x100 as a slop to account for cases where the
+        last line has executable code.  */
+      if (i >= section->lineno_count
+         && last_value != 0
+         && offset - last_value > 0x100)
+       {
+         *functionname_ptr = NULL;
+         *line_ptr = 0;
+       }
     }
 
   /* Cache the results for the next call.  */
This page took 0.024853 seconds and 4 git commands to generate.