gdb: remove symbol value macros
[binutils-gdb.git] / bfd / coffgen.c
index 017d4c31a4e61b50dade6fcc8305c62e62f87fe1..57f380a64250dc5ecb0d5782b7c195b4b317983e 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for the generic parts of COFF, for BFD.
-   Copyright (C) 1990-2021 Free Software Foundation, Inc.
+   Copyright (C) 1990-2022 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -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,
@@ -1078,6 +1092,7 @@ coff_write_alien_symbol (bfd *abfd,
        memset (isym, 0, sizeof (*isym));
       return true;
     }
+  memset (dummy, 0, sizeof dummy);
   native = dummy;
   native->is_sym = true;
   native[1].is_sym = false;
@@ -1358,6 +1373,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 +1400,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 +1417,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 +1708,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 +1722,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 +1853,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 +1918,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 +1928,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 +1945,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 +2075,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,10 +2131,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))
-       / sizeof (combined_entry_type));
+    ret->value
+      = (((bfd_hostptr_t) coffsymbol (symbol)->native->u.syment.n_value
+         - (bfd_hostptr_t) obj_raw_syments (abfd))
+        / sizeof (combined_entry_type));
 }
 
 /* Print out information about COFF symbol.  */
@@ -2094,10 +2182,11 @@ 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 = (((bfd_hostptr_t) 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",
+         fprintf (file, "(sec %2d)(fl 0x%02x)(ty %4x)(scl %3d) (nx %d) 0x",
                   combined->u.syment.n_scnum,
                   combined->u.syment.n_flags,
                   combined->u.syment.n_type,
@@ -2126,6 +2215,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:
@@ -2287,7 +2382,7 @@ coff_find_nearest_line_with_names (bfd *abfd,
        }
 
       if (sec_data != NULL && sec_data->saved_bias)
-       bias = sec_data->saved_bias;
+       bias = sec_data->bias;
       else if (symbols)
        {
          bias = _bfd_dwarf2_find_symbol_bias (symbols,