sim: msp430: delete redundant comments & settings
[binutils-gdb.git] / bfd / coffgen.c
index b13e7732962bcdc52b6e66d1291b5da46d11a5e1..5474f6c24d8d35d513ebb0fe36912aae236d649a 100644 (file)
@@ -847,6 +847,34 @@ coff_mangle_symbols (bfd *bfd_ptr)
     }
 }
 
+static void
+coff_write_auxent_fname (bfd *abfd,
+                        char *str,
+                        union internal_auxent *auxent,
+                        bfd_size_type *string_size_p)
+{
+  unsigned int str_length = strlen (str);
+  unsigned int filnmlen = bfd_coff_filnmlen (abfd);
+
+  if (bfd_coff_long_filenames (abfd))
+    {
+      if (str_length <= filnmlen)
+       strncpy (auxent->x_file.x_n.x_fname, str, filnmlen);
+      else
+       {
+         auxent->x_file.x_n.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
+         auxent->x_file.x_n.x_n.x_zeroes = 0;
+         *string_size_p += str_length + 1;
+       }
+    }
+  else
+    {
+      strncpy (auxent->x_file.x_n.x_fname, str, filnmlen);
+      if (str_length > filnmlen)
+       str[filnmlen] = '\0';
+    }
+}
+
 static void
 coff_fix_symbol_name (bfd *abfd,
                      asymbol *symbol,
@@ -856,7 +884,6 @@ coff_fix_symbol_name (bfd *abfd,
                      bfd_size_type *debug_string_size_p)
 {
   unsigned int name_length;
-  union internal_auxent *auxent;
   char *name = (char *) (symbol->name);
 
   if (name == NULL)
@@ -871,8 +898,6 @@ coff_fix_symbol_name (bfd *abfd,
   if (native->u.syment.n_sclass == C_FILE
       && native->u.syment.n_numaux > 0)
     {
-      unsigned int filnmlen;
-
       if (bfd_coff_force_symnames_in_strings (abfd))
        {
          native->u.syment._n._n_n._n_offset =
@@ -884,27 +909,8 @@ coff_fix_symbol_name (bfd *abfd,
        strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN);
 
       BFD_ASSERT (! (native + 1)->is_sym);
-      auxent = &(native + 1)->u.auxent;
-
-      filnmlen = bfd_coff_filnmlen (abfd);
-
-      if (bfd_coff_long_filenames (abfd))
-       {
-         if (name_length <= filnmlen)
-           strncpy (auxent->x_file.x_fname, name, filnmlen);
-         else
-           {
-             auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE;
-             auxent->x_file.x_n.x_zeroes = 0;
-             *string_size_p += name_length + 1;
-           }
-       }
-      else
-       {
-         strncpy (auxent->x_file.x_fname, name, filnmlen);
-         if (name_length > filnmlen)
-           name[filnmlen] = '\0';
-       }
+      coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent,
+                              string_size_p);
     }
   else
     {
@@ -1029,6 +1035,14 @@ coff_write_symbol (bfd *abfd,
       for (j = 0; j < native->u.syment.n_numaux; j++)
        {
          BFD_ASSERT (! (native + j + 1)->is_sym);
+
+         /* Adjust auxent only if this isn't the filename
+            auxiliary entry.  */
+         if (native->u.syment.n_sclass == C_FILE
+             && (native + j + 1)->u.auxent.x_file.x_ftype)
+           coff_write_auxent_fname (abfd, (char *) (native + j + 1)->extrap,
+                                    &(native + j + 1)->u.auxent, string_size_p);
+
          bfd_coff_swap_aux_out (abfd,
                                 &((native + j + 1)->u.auxent),
                                 type, n_sclass, (int) j,
@@ -1358,6 +1372,7 @@ coff_write_symbols (bfd *abfd)
          size_t name_length = strlen (q->name);
          coff_symbol_type *c_symbol = coff_symbol_from (q);
          size_t maxlen;
+         bool is_c_file = false;
 
          /* Figure out whether the symbol name should go in the string
             table.  Symbol names that are short enough are stored
@@ -1384,6 +1399,7 @@ coff_write_symbols (bfd *abfd)
          else if (c_symbol->native->u.syment.n_sclass == C_FILE
                   && c_symbol->native->u.syment.n_numaux > 0)
            {
+             is_c_file=true;
              if (bfd_coff_force_symnames_in_strings (abfd))
                {
                  if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6)
@@ -1400,6 +1416,35 @@ coff_write_symbols (bfd *abfd)
                             abfd) != name_length + 1)
                return false;
            }
+
+         /* Add strings for C_FILE aux entries. */
+         if (is_c_file
+             && c_symbol->native->u.syment.n_numaux > 1)
+           {
+             for (int j = 1; j < c_symbol->native->u.syment.n_numaux; j++)
+               {
+                 char *str;
+                 size_t str_length;
+
+                 /* Add strings from aux entries only if this isn't the
+                    filename auxiliary entry.  */
+                 if (!c_symbol->native[j + 1].u.auxent.x_file.x_ftype)
+                   continue;
+
+                 if (c_symbol->native[j + 1].u.auxent.x_file.x_n.x_fname[0] != 0)
+                   continue;
+
+                 str = (char *) c_symbol->native[j + 1].extrap;
+                 str_length = strlen (str);
+                 if (str_length > maxlen)
+                   {
+                     if (bfd_bwrite ((void *) (str), (bfd_size_type) str_length + 1,
+                                     abfd) != str_length + 1)
+                       return false;
+                   }
+
+               }
+           }
        }
     }
   else
@@ -1662,8 +1707,10 @@ _bfd_coff_read_string_table (bfd *abfd)
   char extstrsize[STRING_SIZE_SIZE];
   bfd_size_type strsize;
   char *strings;
-  file_ptr pos;
+  ufile_ptr pos;
   ufile_ptr filesize;
+  size_t symesz;
+  size_t size;
 
   if (obj_coff_strings (abfd) != NULL)
     return obj_coff_strings (abfd);
@@ -1674,9 +1721,16 @@ _bfd_coff_read_string_table (bfd *abfd)
       return NULL;
     }
 
+  symesz = bfd_coff_symesz (abfd);
   pos = obj_sym_filepos (abfd);
-  pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
-  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+  if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size)
+      || pos + size < pos)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return NULL;
+    }
+
+  if (bfd_seek (abfd, pos + size, SEEK_SET) != 0)
     return NULL;
 
   if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd)
@@ -1798,7 +1852,7 @@ coff_get_normalized_symtab (bfd *abfd)
 
   /* Mark the end of the symbols.  */
   symesz = bfd_coff_symesz (abfd);
-  raw_end = (char *) raw_src + obj_raw_syment_count (abfd) * symesz;
+  raw_end = PTR_ADD (raw_src, obj_raw_syment_count (abfd) * symesz);
 
   /* FIXME SOMEDAY.  A string table size of zero is very weird, but
      probably possible.  If one shows up, it will probably kill us.  */
@@ -1863,7 +1917,7 @@ coff_get_normalized_symtab (bfd *abfd)
             the text ".file" is redundant.  */
          BFD_ASSERT (! aux->is_sym);
 
-         if (aux->u.auxent.x_file.x_n.x_zeroes == 0)
+         if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0)
            {
              /* The filename is a long one, point into the string table.  */
              if (string_table == NULL)
@@ -1873,12 +1927,12 @@ coff_get_normalized_symtab (bfd *abfd)
                    return NULL;
                }
 
-             if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_offset)
+             if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset)
                  >= obj_coff_strings_len (abfd))
                internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>");
              else
                internal_ptr->u.syment._n._n_n._n_offset =
-                 (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_offset));
+                 (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset));
            }
          else
            {
@@ -1890,15 +1944,48 @@ coff_get_normalized_symtab (bfd *abfd)
                internal_ptr->u.syment._n._n_n._n_offset =
                  (bfd_hostptr_t)
                  copy_name (abfd,
-                            aux->u.auxent.x_file.x_fname,
+                            aux->u.auxent.x_file.x_n.x_fname,
                             internal_ptr->u.syment.n_numaux * symesz);
              else
                internal_ptr->u.syment._n._n_n._n_offset =
                  ((bfd_hostptr_t)
                   copy_name (abfd,
-                             aux->u.auxent.x_file.x_fname,
+                             aux->u.auxent.x_file.x_n.x_fname,
                              (size_t) bfd_coff_filnmlen (abfd)));
            }
+
+         /* Normalize other strings available in C_FILE aux entries.  */
+         if (!coff_data (abfd)->pe)
+           for (int numaux = 1; numaux < internal_ptr->u.syment.n_numaux; numaux++)
+             {
+               aux = internal_ptr + numaux + 1;
+               BFD_ASSERT (! aux->is_sym);
+
+               if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0)
+                 {
+                   /* The string information is a long one, point into the string table.  */
+                   if (string_table == NULL)
+                     {
+                       string_table = _bfd_coff_read_string_table (abfd);
+                       if (string_table == NULL)
+                         return NULL;
+                     }
+
+                   if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset)
+                       >= obj_coff_strings_len (abfd))
+                     aux->u.auxent.x_file.x_n.x_n.x_offset = (bfd_hostptr_t) _("<corrupt>");
+                   else
+                     aux->u.auxent.x_file.x_n.x_n.x_offset =
+                       (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset));
+                 }
+               else
+                 aux->u.auxent.x_file.x_n.x_n.x_offset =
+                   ((bfd_hostptr_t)
+                    copy_name (abfd,
+                               aux->u.auxent.x_file.x_n.x_fname,
+                               (size_t) bfd_coff_filnmlen (abfd)));
+             }
+
        }
       else
        {
@@ -1987,7 +2074,7 @@ coff_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
       return -1;
     }
 #endif
-  return (asect->reloc_count + 1) * sizeof (arelent *);
+  return (asect->reloc_count + 1L) * sizeof (arelent *);
 }
 
 asymbol *
@@ -2043,8 +2130,10 @@ coff_get_symbol_info (bfd *abfd, asymbol *symbol, symbol_info *ret)
   if (coffsymbol (symbol)->native != NULL
       && coffsymbol (symbol)->native->fix_value
       && coffsymbol (symbol)->native->is_sym)
-    ret->value = coffsymbol (symbol)->native->u.syment.n_value -
-      (bfd_hostptr_t) obj_raw_syments (abfd);
+    ret->value =
+      ((coffsymbol (symbol)->native->u.syment.n_value -
+       (bfd_hostptr_t) obj_raw_syments (abfd))
+       / sizeof (combined_entry_type));
 }
 
 /* Print out information about COFF symbol.  */
@@ -2092,7 +2181,8 @@ coff_print_symbol (bfd *abfd,
          if (! combined->fix_value)
            val = (bfd_vma) combined->u.syment.n_value;
          else
-           val = combined->u.syment.n_value - (bfd_hostptr_t) root;
+           val = ((combined->u.syment.n_value - (bfd_hostptr_t) root)
+                  / sizeof (combined_entry_type));
 
          fprintf (file, "(sec %2d)(fl 0x%02x)(ty %3x)(scl %3d) (nx %d) 0x",
                   combined->u.syment.n_scnum,
@@ -2123,6 +2213,12 @@ coff_print_symbol (bfd *abfd,
                {
                case C_FILE:
                  fprintf (file, "File ");
+                 /* Add additional information if this isn't the filename
+                    auxiliary entry.  */
+                 if (auxp->u.auxent.x_file.x_ftype)
+                   fprintf (file, "ftype %d fname \"%s\"",
+                            auxp->u.auxent.x_file.x_ftype,
+                            (char *) auxp->u.auxent.x_file.x_n.x_n.x_offset);
                  break;
 
                case C_DWARF: