Add arm-epoc-pe specific linker script
[deliverable/binutils-gdb.git] / bfd / coffgen.c
index df413833bd3c6251a537229a7df5905d8dd50ed8..547a15f883cadc79e4303d60c9f2676dfc600f86 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.
 
@@ -140,9 +140,9 @@ make_a_section_from_file (abfd, hdr, target_index)
   return_section->lineno_count = hdr->s_nlnno;
   return_section->userdata = NULL;
   return_section->next = (asection *) NULL;
-  return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name);
-
   return_section->target_index = target_index;
+  return_section->flags = bfd_coff_styp_to_sec_flags_hook (abfd, hdr, name,
+                                                          return_section);
 
   /* At least on i386-coff, the line number count for a shared library
      section must be ignored.  */
@@ -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)
@@ -585,7 +585,8 @@ fixup_symbol_value (abfd, coff_symbol_ptr, syment)
       syment->n_scnum = N_UNDEF;
       syment->n_value = coff_symbol_ptr->symbol.value;
     }
-  else if (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING)
+  else if ((coff_symbol_ptr->symbol.flags & BSF_DEBUGGING) != 0
+          && (coff_symbol_ptr->symbol.flags & BSF_DEBUGGING_RELOC) == 0)
     {
       syment->n_value = coff_symbol_ptr->symbol.value;
     }
@@ -594,6 +595,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)
@@ -810,14 +812,18 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p,
   if (native->u.syment.n_sclass == C_FILE
       && native->u.syment.n_numaux > 0)
     {
+      unsigned int filnmlen;
+
       strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
       auxent = &(native + 1)->u.auxent;
 
+      filnmlen = bfd_coff_filnmlen (abfd);
+
       if (bfd_coff_long_filenames (abfd))
        {
-         if (name_length <= FILNMLEN)
+         if (name_length <= filnmlen)
            {
-             strncpy (auxent->x_file.x_fname, name, FILNMLEN);
+             strncpy (auxent->x_file.x_fname, name, filnmlen);
            }
          else
            {
@@ -828,11 +834,9 @@ coff_fix_symbol_name (abfd, symbol, native, string_size_p,
        }
       else
        {
-         strncpy (auxent->x_file.x_fname, name, FILNMLEN);
-         if (name_length > FILNMLEN)
-           {
-             name[FILNMLEN] = '\0';
-           }
+         strncpy (auxent->x_file.x_fname, name, filnmlen);
+         if (name_length > filnmlen)
+           name[filnmlen] = '\0';
        }
     }
   else
@@ -1246,7 +1250,7 @@ coff_write_symbols (abfd)
            }
          else if (c_symbol->native->u.syment.n_sclass == C_FILE
                   && c_symbol->native->u.syment.n_numaux > 0)
-           maxlen = FILNMLEN;
+           maxlen = bfd_coff_filnmlen (abfd);
          else
            maxlen = SYMNMLEN;
 
@@ -1351,7 +1355,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 +1750,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,
+                               bfd_coff_filnmlen (abfd)));
+               }
            }
        }
       else
@@ -1847,8 +1867,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)
@@ -2046,8 +2066,23 @@ coff_print_symbol (abfd, filep, symbol, how)
                                 auxp->u.auxent.x_scn.x_comdat);
                      break;
                    }
+                   /* else fall through */
+               case C_EXT:
+                 if (ISFCN (combined->u.syment.n_type))
+                   {
+                     fprintf (file,
+                              _("AUX tagndx %ld ttlsiz 0x%lx lnnos %ld next %ld"),
+                              tagndx,
+                              auxp->u.auxent.x_sym.x_misc.x_fsize,
+                              auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_lnnoptr,
+                              (auxp->fix_end
+                               ? ((long)
+                                  (auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.p
+                                   - root))
+                               : auxp->u.auxent.x_sym.x_fcnary.x_fcn.x_endndx.l));
+                     break;
+                   }
                  /* else fall through */
-
                default:
                  fprintf (file, "AUX lnno %d size 0x%x tagndx %ld",
                           auxp->u.auxent.x_sym.x_misc.x_lnsz.x_lnno,
@@ -2095,7 +2130,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 +2225,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 +2266,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 +2279,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 +2308,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.027456 seconds and 4 git commands to generate.