more vms work from Pat Rankin
authorKen Raeburn <raeburn@cygnus>
Mon, 19 Sep 1994 16:36:31 +0000 (16:36 +0000)
committerKen Raeburn <raeburn@cygnus>
Mon, 19 Sep 1994 16:36:31 +0000 (16:36 +0000)
gas/config/obj-vms.c
gas/config/obj-vms.h

index 647067da5d08bdd2ef335624cde08636ebf64d7a..3ff5718284b1a758f1641e3cdfb58d7d3d8592a6 100644 (file)
@@ -1,5 +1,5 @@
 /* vms.c -- Write out a VAX/VMS object file
-   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1992, 1994 Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -191,6 +191,12 @@ static int final_pass;
  */
 static int struct_number;
 
+/* This is used to distinguish between D_float and G_float for telling
+   the debugger about doubles.  gcc outputs the same .stabs regardless
+   of whether -mg is used to select alternate doubles.  */
+
+static int vax_g_doubles = 0;
+
 
 /*
  * Variable descriptors are used tell the debugger the data types of certain
@@ -322,7 +328,7 @@ const segT N_TYPE_seg[N_TYPE + 2] =
  *  use with VMS.
  */
 
-char const_flag = 0;
+char const_flag = IN_DEFAULT_SECTION;
 
 void
 s_const ()
@@ -366,7 +372,7 @@ vms_resolve_symbol_redef (sym)
       as_warn ("compiler redefined zero-size common symbol `%s'",
               S_GET_NAME (sym));
       sym->sy_frag  = frag_now;
-      S_GET_OTHER(sym) = const_flag;
+      S_SET_OTHER(sym, const_flag);
       S_SET_VALUE(sym, obstack_next_free(& frags) - frag_now->fr_literal);
       /* Keep N_EXT bit.  */
       sym->sy_symbol.n_type |= SEGMENT_TO_SYMBOL_TYPE((int) now_seg);
@@ -376,6 +382,38 @@ vms_resolve_symbol_redef (sym)
   return 0;
 }
 
+/* `tc_frob_label' handler for colon(symbols.c), used to examine the
+   dummy label(s) gcc inserts at the beginning of each file it generates.
+   gcc 1.x put "gcc_compiled."; gcc 2.x (as of 2.6) puts "gcc2_compiled."
+   and "__gnu_language_<name>" and possibly "__vax_<type>_doubles".  */
+
+void
+vms_check_for_special_label (symbolP) 
+symbolS *symbolP;
+{
+  /* Special labels only occur prior to explicit section directives.  */
+  if ((const_flag & IN_DEFAULT_SECTION) != 0)
+    {
+      char *sym_name = S_GET_NAME(symbolP);
+
+      if (*sym_name == '_')
+       ++sym_name;
+
+      if (!strcmp (sym_name, "__vax_g_doubles"))
+       vax_g_doubles = 1;
+#if 0  /* not necessary */
+      else if (!strcmp (sym_name, "__vax_d_doubles"))
+       vax_g_doubles = 0;
+#endif
+#if 0  /* these are potential alternatives to tc-vax.c's md_parse_options() */
+      else if (!strcmp (sym_name, "gcc_compiled."))
+       flag_one = 1;
+      else if (!strcmp (sym_name, "__gnu_language_cplusplus"))
+       flag_hash_long_names = 1;
+#endif
+    }
+  return;
+}
 
 void 
 obj_read_begin_hook ()
@@ -932,7 +970,7 @@ VMS_TBT_Routine_End (Max_Size, sp)
   symbolS *symbolP;
   int Size = 0x7fffffff;
   char Local[16];
-
+  valueT sym_value, sp_value = S_GET_VALUE (sp);
 
   for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
     {
@@ -940,21 +978,27 @@ VMS_TBT_Routine_End (Max_Size, sp)
        {
          if (*S_GET_NAME (symbolP) == 'L')
            continue;
-         if ((S_GET_VALUE (symbolP) > S_GET_VALUE (sp)) &&
-             (S_GET_VALUE (symbolP) < Size))
-           Size = S_GET_VALUE (symbolP);
+         sym_value = S_GET_VALUE (symbolP);
+         if (sym_value > sp_value && sym_value < Size)
+           Size = sym_value;
+
+         /*
+          * Dummy labels like "gcc_compiled." should no longer reach here.
+          */
+#if 0
+         else
          /* check if gcc_compiled. has size of zero */
-         if ((S_GET_VALUE (symbolP) == S_GET_VALUE (sp)) &&
+         if (sym_value == sp_value &&
              sp != symbolP &&
              (!strcmp (S_GET_NAME (sp), "gcc_compiled.") ||
               !strcmp (S_GET_NAME (sp), "gcc2_compiled.")))
-           Size = S_GET_VALUE (symbolP);
-
+           Size = sym_value;
+#endif
        }
     }
   if (Size == 0x7fffffff)
     Size = Max_Size;
-  Size -= S_GET_VALUE (sp);    /* and get the size of the routine */
+  Size -= sp_value;            /* and get the size of the routine */
   /*
    *   Record Size
    */
@@ -1247,7 +1291,7 @@ VMS_TBT_Source_File (Filename, ID_Number)
   Status = sys$open (&Fab);
   if (!(Status & 1))
     {
-      printf ("gas: Couldn't find source file \"%s\", Error = %%X%x\n",
+      printf ("gas: Couldn't find source file \"%s\", status=%%X%x\n",
              Filename, Status);
       return (0);
     }
@@ -1467,7 +1511,7 @@ find_file (sp)
 
 
 /* This routine converts a number string into an integer, and stops when it
- * sees an invalid character the return value is the address of the character
+ * sees an invalid character.  The return value is the address of the character
  * just past the last character read.  No error is generated.
  */
 static char *
@@ -1477,7 +1521,7 @@ cvt_integer (str, rtn)
 {
   int ival, neg;
   neg = *str == '-' ? ++str, -1 : 1;
-  ival = 0;                    /* first get the number of the type for dbx */
+  ival = 0;
   while ((*str <= '9') && (*str >= '0'))
     ival = 10 * ival + *str++ - '0';
   *rtn = neg * ival;
@@ -1643,18 +1687,19 @@ array_suffix (spnt2)
       spnt1 = find_symbol (spnt1->type2);
     }
   total_size = total_size * spnt1->data_size;
-  push (spnt1->data_size, 2);
+  push (spnt1->data_size, 2);  /* element size */
   if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
     push (0, 1);
   else
-    push (spnt1->VMS_type, 1);
-  push (4, 1);
-  for (i = 0; i < 6; i++)
-    push (0, 1);
-  push (0xc0, 1);
-  push (rank, 1);
+    push (spnt1->VMS_type, 1); /* element type */
+  push (DSC_K_CLASS_A, 1);     /* descriptor class */
+  push (0, 4);                 /* base address */
+  push (0, 1);                 /* scale factor -- not applicable */
+  push (0, 1);                 /* digit count -- not applicable */
+  push (0xc0, 1);              /* flags: multiplier block & bounds present */
+  push (rank, 1);              /* number of dimensions */
   push (total_size, 4);
-  push (0, 4);
+  push (0, 4);                 /* pointer to element [0][0]...[0] */
   spnt1 = spnt;
   while (spnt1->advanced == ARRAY)
     {
@@ -1673,7 +1718,7 @@ array_suffix (spnt2)
 /* this routine generates the start of a variable descriptor based upon
  * a struct/union/enum that has yet to be defined.  We define this spot as
  * a new location, and save four bytes for the address.  When the struct is
- * finally defined, then we can go back and plug in the correct address
+ * finally defined, then we can go back and plug in the correct address.
 */
 static
 new_forward_ref (dbx_type)
@@ -1686,7 +1731,7 @@ new_forward_ref (dbx_type)
   fpnt->dbx_type = dbx_type;
   fpnt->struc_numb = ++structure_count;
   fpnt->resolved = 'N';
-  push (3, -1);
+  push (DST_K_TS_IND, -1);     /* indirect type specification */
   total_len = 5;
   push (total_len, -2);
   struct_number = -fpnt->struc_numb;
@@ -1723,7 +1768,8 @@ gen1 (spnt, array_suffix_len)
          return 1;
        }
       push (0, -4);
-      push (0xfa02, -2);
+      push (DST_K_VFLAGS_DSC, -1);
+      push (DST_K_TS_DSC, -1); /* descriptor type specification */
       total_len = -2;
       return 1;
     case STRUCT:
@@ -1742,7 +1788,7 @@ gen1 (spnt, array_suffix_len)
     case POINTER:
       spnt1 = find_symbol (spnt->type2);
       i = 1;
-      if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
+      if (!spnt1)
        new_forward_ref (spnt->type2);
       else
        i = gen1 (spnt1, 0);
@@ -1758,7 +1804,7 @@ gen1 (spnt, array_suffix_len)
       while (spnt1->advanced == ARRAY)
        {
          spnt1 = find_symbol (spnt1->type2);
-         if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
+         if (!spnt1)
            {
              printf ("gcc-as warning(debugger output):");
              printf ("Forward reference error, dbx type %d\n",
@@ -1781,8 +1827,9 @@ gen1 (spnt, array_suffix_len)
          push (0, -2);
          total_len += 2;
          push (total_len, -2);
-         push (0xfa, -1);
-         push (0x0101, -2);
+         push (DST_K_VFLAGS_DSC, -1);
+         push (1, -1);         /* flags: element value spec included */
+         push (1, -1);         /* one dimension */
          push (DBG_S_C_COMPLEX_ARRAY, -1);
        }
       total_len += array_suffix_len + 8;
@@ -1801,16 +1848,22 @@ generate_suffix (spnt, dbx_type)
      struct VMS_DBG_Symbol *spnt;
      int dbx_type;
 {
+  static CONST char pvoid[6] = {
+               5,              /* record.length == 5 */
+               DST_K_TYPSPEC,  /* record.type == 1 (type specification) */
+               0,              /* name.length == 0, no name follows */
+               1, 0,           /* type.length == 1 {2 bytes, little endian} */
+               DBG_S_C_VOID    /* type.type == 5 (pointer to unspecified) */
+  };
   int ilen;
   int i;
-  static CONST char pvoid[6] = {5, 0xaf, 0, 1, 0, 5};
   struct VMS_DBG_Symbol *spnt1;
   Apoint = 0;
   Lpnt = MAX_DEBUG_RECORD - 1;
   total_len = 0;
   struct_number = 0;
   overflow = 0;
-  if (spnt == (struct VMS_DBG_Symbol *) NULL)
+  if (!spnt)
     new_forward_ref (dbx_type);
   else
     {
@@ -1818,7 +1871,8 @@ generate_suffix (spnt, dbx_type)
        return 0;               /* no suffix needed */
       gen1 (spnt, 0);
     }
-  push (0x00af, -2);
+  push (0, -1);                /* no name (len==0) */
+  push (DST_K_TYPSPEC, -1);
   total_len += 4;
   push (total_len, -1);
 /* if the variable descriptor overflows the record, output a descriptor for
@@ -1851,8 +1905,8 @@ generate_suffix (spnt, dbx_type)
       VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
       Lpnt = 0;
       VMS_Def_Struct (struct_number);
-      for (i = 0; i < 4; i++)
-       Local[Lpnt++] = 0;
+      COPY_LONG(&Local[Lpnt], 0L);
+      Lpnt += 4;
       VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
       Lpnt = 0;
     }
@@ -1864,8 +1918,82 @@ generate_suffix (spnt, dbx_type)
   Lpnt = 0;
 }
 
-/* This routine generates a symbol definition for a C sybmol for the debugger.
- * It takes a psect and offset for global symbols - if psect < 0, then this is
+       /* "novel length" type doesn't work for simple atomic types */
+#define USE_BITSTRING_DESCRIPTOR(t) ((t)->advanced == BASIC)
+#undef SETUP_BASIC_TYPES
+
+static void
+bitfield_suffix (spnt, width)
+     struct VMS_DBG_Symbol *spnt;
+     int width;
+{
+  Local[Lpnt++] = 13;                  /* rec.len==13 */
+  Local[Lpnt++] = DST_K_TYPSPEC;       /* a type specification record */
+  Local[Lpnt++] = 0;                   /* not named */
+  COPY_SHORT(&Local[Lpnt], 9);         /* typ.len==9 */
+  Lpnt += 2;
+  Local[Lpnt++] = DST_K_TS_NOV_LENG;   /* This type is a "novel length"
+                                          incarnation of some other type.  */
+  COPY_LONG(&Local[Lpnt], width);      /* size in bits == novel length */
+  Lpnt += 4;
+  VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+  Lpnt = 0;
+  /* assert( spnt->struc_numb > 0 ); */
+  VMS_Store_Struct (spnt->struc_numb); /* output 4 more bytes */
+}
+
+/* Formally define a builtin type, so that it can serve as the target of
+   an indirect reference.  It makes bitfield_suffix() easier by avoiding
+   the need to use a forward reference for the first occurrence of each
+   type used in a bitfield.  */
+static void
+setup_basic_type (spnt)
+     struct VMS_DBG_Symbol *spnt;
+{
+#ifdef SETUP_BASIC_TYPES
+  /* This would be very useful if "novel length" fields actually worked
+     with basic types like they do with enumerated types.  However,
+     they do not, so this isn't worth doing just so that you can use
+     EXAMINE/TYPE=(__long_long_int) instead of EXAMINE/QUAD.  */
+  char *p;
+#ifndef SETUP_SYNONYM_TYPES
+  /* This determines whether compatible things like `int' and `long int'
+     ought to have distinct type records rather than sharing one.  */
+  struct VMS_DBG_Symbol *spnt2;
+
+  /* first check whether this type has already been seen by another name */
+  for (spnt2 = VMS_Symbol_type_list; spnt2; spnt2 = spnt2->next)
+    if (spnt2 != spnt && spnt2->VMS_type == spnt->VMS_type)
+      {
+       spnt->struc_numb = spnt2->struc_numb;
+       return;
+      }
+#endif
+
+  /* `structure number' doesn't really mean `structure'; it means an index
+     into a linker maintained set of saved locations which can be referenced
+     again later.  */
+  spnt->struc_numb = ++structure_count;
+  VMS_Def_Struct (spnt->struc_numb);   /* remember where this type lives */
+  /* define the simple scalar type */
+  Local[Lpnt++] = 6 + strlen (symbol_name) + 2;        /* rec.len */
+  Local[Lpnt++] = DST_K_TYPSPEC;       /* rec.typ==type specification */
+  Local[Lpnt++] = strlen (symbol_name) + 2;
+  Local[Lpnt++] = '_';                 /* prefix name with "__" */
+  Local[Lpnt++] = '_';
+  for (p = symbol_name; *p; p++)
+    Local[Lpnt++] = *p == ' ' ? '_' : *p;
+  COPY_SHORT(&Local[Lpnt], 2);         /* typ.len==2 */
+  Lpnt += 2;
+  Local[Lpnt++] = DST_K_TS_ATOM;       /* typ.kind is simple type */
+  Local[Lpnt++] = spnt->VMS_type;      /* typ.type */
+  VMS_Store_Immediate_Data (Local, Lpnt, OBJ_S_C_DBG);
+  Lpnt = 0;
+#endif /* SETUP_BASIC_TYPES */
+}
+
+/* This routine generates a symbol definition for a C symbol for the debugger.
+ * It takes a psect and offset for global symbols; if psect < 0, then this is
  * a local variable and the offset is relative to FP.  In this case it can
  * be either a variable (Offset < 0) or a parameter (Offset > 0).
  */
@@ -1879,32 +2007,29 @@ VMS_DBG_record (spnt, Psect, Offset, Name)
   char *pnt;
   char *Name_pnt;
   int j;
-  int maxlen;
+  int len;
   int i = 0;
+
   Name_pnt = fix_name (Name);  /* if there are bad characters in name, convert them */
+  len = strlen(Name_pnt);
   if (Psect < 0)
     {                          /* this is a local variable, referenced to SP */
-      maxlen = 7 + strlen (Name_pnt);
-      Local[i++] = maxlen;
+      Local[i++] = 7 + len;
       Local[i++] = spnt->VMS_type;
-      if (Offset > 0)
-       Local[i++] = DBG_S_C_FUNCTION_PARAMETER;
-      else
-       Local[i++] = DBG_S_C_LOCAL_SYM;
+      Local[i++] = (Offset > 0) ? DBG_C_FUNCTION_PARAM : DBG_C_LOCAL_SYM;
       COPY_LONG (&Local[i], Offset);
       i += 4;
     }
   else
     {
-      maxlen = 7 + strlen (Name_pnt);  /* symbols fixed in memory */
-      Local[i++] = 7 + strlen (Name_pnt);
+      Local[i++] = 7 + len;
       Local[i++] = spnt->VMS_type;
-      Local[i++] = 1;
+      Local[i++] = DST_K_VALKIND_ADDR;
       VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
       i = 0;
       VMS_Set_Data (Psect, Offset, OBJ_S_C_DBG, 0);
     }
-  Local[i++] = strlen (Name_pnt);
+  Local[i++] = len;
   while (*Name_pnt != '\0')
     Local[i++] = *Name_pnt++;
   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
@@ -1926,7 +2051,6 @@ VMS_local_stab_Parse (sp)
   struct VMS_DBG_Symbol *spnt;
   struct VMS_Symbol *vsp;
   int dbx_type;
-  int VMS_type;
   dbx_type = 0;
   str = S_GET_NAME (sp);
   pnt = (char *) strchr (str, ':');
@@ -1977,7 +2101,7 @@ VMS_local_stab_Parse (sp)
   }                            /* p block */
   pnt = cvt_integer (pnt, &dbx_type);
   spnt = find_symbol (dbx_type);
-  if (spnt == (struct VMS_DBG_Symbol *) NULL)
+  if (!spnt)
     return 0;                  /*Dunno what this is*/
   *pnt1 = '\0';
   VMS_DBG_record (spnt, -1, S_GET_VALUE (sp), str);
@@ -2010,7 +2134,6 @@ VMS_stab_parse (sp, expected_type, type1, type2, Text_Psect)
   struct VMS_DBG_Symbol *spnt;
   struct VMS_Symbol *vsp;
   int dbx_type;
-  int VMS_type;
   dbx_type = 0;
   str = S_GET_NAME (sp);
   pnt = (char *) strchr (str, ':');
@@ -2132,12 +2255,13 @@ VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
   int dbx_type;
   struct VMS_DBG_Symbol *spnt;
   int j;
-  int maxlen;
+  int len;
   int i = 0;
   int bcnt = 0;
   int Min_Offset = -1;         /* min PC of validity */
   int Max_Offset = 0;          /* max PC of validity */
   symbolS *symbolP;
+
   for (symbolP = sp; symbolP; symbolP = symbol_next (symbolP))
     {
       /*
@@ -2205,35 +2329,31 @@ VMS_RSYM_Parse (sp, Current_Routine, Text_Psect)
     return 0;
   pnt = cvt_integer (pnt + 1, &dbx_type);
   spnt = find_symbol (dbx_type);
-  if (spnt == (struct VMS_DBG_Symbol *) NULL)
+  if (!spnt)
     return 0;                  /*Dunno what this is yet*/
   *pnt1 = '\0';
   pnt = fix_name (S_GET_NAME (sp));    /* if there are bad characters in name, convert them */
-  maxlen = 25 + strlen (pnt);
-  Local[i++] = maxlen;
+  len = strlen(pnt);
+  Local[i++] = 25 + len;
   Local[i++] = spnt->VMS_type;
-  Local[i++] = 0xfb;
-  Local[i++] = strlen (pnt) + 1;
-  Local[i++] = 0x00;
-  Local[i++] = 0x00;
-  Local[i++] = 0x00;
-  Local[i++] = strlen (pnt);
+  Local[i++] = DST_K_VFLAGS_TVS;       /* trailing value specified */
+  COPY_LONG(&Local[i], 1 + len);       /* relative offset, beyond name */
+  i += 4;
+  Local[i++] = len;                    /* name length (ascic prefix) */
   while (*pnt != '\0')
     Local[i++] = *pnt++;
-  Local[i++] = 0xfd;
-  Local[i++] = 0x0f;
-  Local[i++] = 0x00;
-  Local[i++] = 0x03;
-  Local[i++] = 0x01;
+  Local[i++] = DST_K_VS_FOLLOWS;       /* value specification follows */
+  COPY_SHORT(&Local[i], 15);           /* length of rest of record */
+  i += 2;
+  Local[i++] = DST_K_VS_ALLOC_SPLIT;   /* split lifetime */
+  Local[i++] = 1;                      /* one binding follows */
   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
   i = 0;
   VMS_Set_Data (Text_Psect, Min_Offset, OBJ_S_C_DBG, 1);
   VMS_Set_Data (Text_Psect, Max_Offset, OBJ_S_C_DBG, 1);
-  Local[i++] = 0x03;
-  Local[i++] = S_GET_VALUE (sp);
-  Local[i++] = 0x00;
-  Local[i++] = 0x00;
-  Local[i++] = 0x00;
+  Local[i++] = DST_K_VALKIND_REG;              /* nested value spec */
+  COPY_LONG(&Local[i], S_GET_VALUE (sp));
+  i += 4;
   VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
   *pnt1 = ':';
   if (spnt->VMS_type == DBG_S_C_ADVANCED_TYPE)
@@ -2283,19 +2403,17 @@ forward_reference (pnt)
 
 static int
 final_forward_reference (spnt)
-  struct VMS_DBG_Symbol * spnt;
+  struct VMS_DBG_Symbol *spnt;
 {
-       struct VMS_DBG_Symbol * spnt1;
-       if(spnt != (struct VMS_DBG_Symbol*) NULL) {
-         while((spnt->advanced == POINTER) || (spnt->advanced == ARRAY)){
-           spnt1 = find_symbol(spnt->type2);
-           if((spnt->advanced == ARRAY) &&
-              (spnt1 == (struct VMS_DBG_Symbol*) NULL))return 1;
-           if(spnt1 == (struct VMS_DBG_Symbol*) NULL) break;
-           spnt=spnt1;
-         }
-       }
-       return 0;       /* no forward refences found */
+  struct VMS_DBG_Symbol *spnt1;
+
+  while (spnt && (spnt->advanced == POINTER || spnt->advanced == ARRAY))
+    {
+      spnt1 = find_symbol(spnt->type2);
+      if (spnt->advanced == ARRAY && !spnt1) return 1;
+      spnt = spnt1;
+    }
+  return 0;    /* no forward refences found */
 }
 
 /* This routine parses the stabs directives to find any definitions of dbx type
@@ -2324,10 +2442,11 @@ VMS_typedef_parse (str)
   int i;
   int dtype;
   struct forward_ref *fpnt;
-  int i1, i2, i3;
+  int i1, i2, i3, len;
   int convert_integer;
   struct VMS_DBG_Symbol *spnt;
   struct VMS_DBG_Symbol *spnt1;
+
 /* check for any nested def's */
   pnt = (char *) strchr (str + 1, '=');
   if ((pnt != (char *) NULL) && (*(str + 1) != '*')
@@ -2347,12 +2466,14 @@ VMS_typedef_parse (str)
   cvt_integer (pnt, &i1);
   spnt = find_symbol (i1);
 /* first we see if this has been defined already, due to a forward reference*/
-  if (spnt == (struct VMS_DBG_Symbol *) NULL)
+  if (!spnt)
     {
       spnt = (struct VMS_DBG_Symbol *) xmalloc (sizeof (struct VMS_DBG_Symbol));
       spnt->next = VMS_Symbol_type_list;
       VMS_Symbol_type_list = spnt;
       spnt->dbx_type = i1;     /* and save the type */
+      spnt->type2 = spnt->VMS_type = spnt->data_size = 0;
+      spnt->index_min = spnt->index_max = spnt->struc_numb = 0;
     }
 /* for structs and unions, do a partial parse, otherwise we sometimes get
  * circular definitions that are impossible to resolve. We read enough info
@@ -2371,7 +2492,7 @@ VMS_typedef_parse (str)
          return 0;
        }
       if (type_check ("unknown type"))
-       {                       /* this is the void symbol */
+       {
          *str = '\0';
          spnt->advanced = UNKNOWN;
          return 0;
@@ -2446,14 +2567,13 @@ VMS_typedef_parse (str)
        }
       else if (type_check ("double"))
        {
-         /* caveat: this assumes D_float, and is not correct for G_float */
-         spnt->VMS_type = DBG_S_C_REAL8;
+         spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
          spnt->data_size = 8;
        }
       else if (type_check ("long double"))
        {
          /* same as double, at least for now */
-         spnt->VMS_type = DBG_S_C_REAL8;
+         spnt->VMS_type = vax_g_doubles ? DBG_S_C_REAL8_G : DBG_S_C_REAL8;
          spnt->data_size = 8;
        }
       else if (type_check ("long long int"))
@@ -2473,14 +2593,13 @@ VMS_typedef_parse (str)
        }
       else if (type_check ("complex double"))
        {
-         /* caveat: this assumes D_float, and is not correct for G_float */
-         spnt->VMS_type = DBG_S_C_COMPLX8;
+         spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
          spnt->data_size = 2 * 8;
        }
       else if (type_check ("complex long double"))
        {
          /* same as complex double, at least for now */
-         spnt->VMS_type = DBG_S_C_COMPLX8;
+         spnt->VMS_type = vax_g_doubles ? DBG_S_C_COMPLX8_G : DBG_S_C_COMPLX8;
          spnt->data_size = 2 * 8;
        }
       else
@@ -2492,14 +2611,13 @@ VMS_typedef_parse (str)
          spnt->VMS_type = 0;
          spnt->data_size = 0;
        }
+      if (spnt->VMS_type != 0)
+       setup_basic_type(spnt);
       pnt1 = (char *) strchr (str, ';') + 1;
       break;
     case 's':
     case 'u':
-      if (*pnt == 's')
-       spnt->advanced = STRUCT;
-      else
-       spnt->advanced = UNION;
+      spnt->advanced = (*pnt == 's') ? STRUCT : UNION;
       spnt->VMS_type = DBG_S_C_ADVANCED_TYPE;
       pnt1 = cvt_integer (pnt + 1, &spnt->data_size);
       if (!final_pass && forward_reference(pnt))
@@ -2511,24 +2629,23 @@ VMS_typedef_parse (str)
       pnt1--;
       pnt = get_struct_name (str);
       VMS_Def_Struct (spnt->struc_numb);
-      fpnt = f_ref_root;
-      while (fpnt != (struct forward_ref *) NULL)
-       {
-         if (fpnt->dbx_type == spnt->dbx_type)
-           {
-             fpnt->resolved = 'Y';
-             VMS_Set_Struct (fpnt->struc_numb);
-             VMS_Store_Struct (spnt->struc_numb);
-           }
-         fpnt = fpnt->next;
-       }
-      VMS_Set_Struct (spnt->struc_numb);
+      i = 0;
+      for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
+       if (fpnt->dbx_type == spnt->dbx_type)
+         {
+           fpnt->resolved = 'Y';
+           VMS_Set_Struct (fpnt->struc_numb);
+           VMS_Store_Struct (spnt->struc_numb);
+           i++;
+         }
+      if (i > 0)
+       VMS_Set_Struct (spnt->struc_numb);
       i = 0;
       Local[i++] = 11 + strlen (pnt);
       Local[i++] = DBG_S_C_STRUCT_START;
-      Local[i++] = 0x80;
-      for (i1 = 0; i1 < 4; i1++)
-       Local[i++] = 0x00;
+      Local[i++] = DST_K_VFLAGS_NOVAL; /* structure definition only */
+      COPY_LONG(&Local[i], 0L);                /* hence value is unused */
+      i += 4;
       Local[i++] = strlen (pnt);
       pnt2 = pnt;
       while (*pnt2 != '\0')
@@ -2551,47 +2668,76 @@ VMS_typedef_parse (str)
          pnt1 = cvt_integer (pnt + 1, &dtype);
          pnt1 = cvt_integer (pnt1 + 1, &i2);
          pnt1 = cvt_integer (pnt1 + 1, &i3);
-         if ((dtype == 1) && (i3 != 32))
+         spnt1 = find_symbol (dtype);
+         len = strlen (pnt2);
+         if (spnt1 && (spnt1->advanced == BASIC || spnt1->advanced == ENUM)
+             && ((i3 != spnt1->data_size * 8) || (i2 % 8 != 0)))
            {                   /* bitfield */
-             Apoint = 0;
-             push (19 + strlen (pnt2), 1);
-             push (0xfa22, 2);
-             push (1 + strlen (pnt2), 4);
-             push (strlen (pnt2), 1);
-             while (*pnt2 != '\0')
-               push (*pnt2++, 1);
-             push (i3, 2);     /* size of bitfield */
-             push (0x0d22, 2);
-             push (0x00, 4);
-             push (i2, 4);     /* start position */
-             VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
-             Apoint = 0;
+             if (USE_BITSTRING_DESCRIPTOR (spnt1))
+               {
+                 /* This uses a type descriptor, which doesn't work if
+                    the enclosing structure has been placed in a register.
+                    Also, enum bitfields degenerate to simple integers.  */
+                 int unsigned_type = (spnt1->VMS_type == DBG_S_C_ULINT
+                                   || spnt1->VMS_type == DBG_S_C_USINT
+                                   || spnt1->VMS_type == DBG_S_C_UCHAR
+                                   || spnt1->VMS_type == DBG_S_C_UQUAD
+                                   || spnt1->advanced == ENUM); /* (approximate) */
+                 Apoint = 0;
+                 push (19 + len, 1);
+                 push (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
+                 push (DST_K_VFLAGS_DSC, 1); /* specified by descriptor */
+                 push (1 + len, 4);    /* relative offset to descriptor */
+                 push (len, 1);                /* length byte (ascic prefix) */
+                 while (*pnt2 != '\0') /* name bytes */
+                   push (*pnt2++, 1);
+                 push (i3, 2);         /* dsc length == size of bitfield */
+                                       /* dsc type == un?signed bitfield */
+                 push (unsigned_type ? DBG_S_C_UBITU : DBG_S_C_SBITU, 1);
+                 push (DSC_K_CLASS_UBS, 1); /* dsc class == unaligned bitstring */
+                 push (0x00, 4);               /* dsc pointer == zeroes */
+                 push (i2, 4);         /* start position */
+                 VMS_Store_Immediate_Data (Asuffix, Apoint, OBJ_S_C_DBG);
+                 Apoint = 0;
+               }
+             else
+               {
+                 /* Use a "novel length" type specification, which works
+                    right for register structures and for enum bitfields
+                    but results in larger object modules.  */
+                 Local[i++] = 7 + len;
+                 Local[i++] = DBG_S_C_ADVANCED_TYPE;   /* type spec follows */
+                 Local[i++] = DBG_S_C_STRUCT_ITEM;     /* value is a bit offset */
+                 COPY_LONG (&Local[i], i2);            /* bit offset */
+                 i += 4;
+                 Local[i++] = strlen (pnt2);
+                 while (*pnt2 != '\0')
+                   Local[i++] = *pnt2++;
+                 VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
+                 i = 0;
+                 bitfield_suffix (spnt1, i3);
+            }
            }
          else
-           {
-             Local[i++] = 7 + strlen (pnt2);
-             spnt1 = find_symbol (dtype);
+           {                   /* not a bitfield */
              /* check if this is a forward reference */
              if(final_pass && final_forward_reference(spnt1))
                {
                  printf("gcc-as warning(debugger output):");
-                 printf("structure element %s has undefined type\n",pnt2);
-                 i--;
+                 printf("structure element `%s' has undefined type\n",pnt2);
                  continue;
                }
-             if (spnt1 != (struct VMS_DBG_Symbol *) NULL)
-               Local[i++] = spnt1->VMS_type;
-             else
-               Local[i++] = DBG_S_C_ADVANCED_TYPE;
+             Local[i++] = 7 + len;
+             Local[i++] = spnt1 ? spnt1->VMS_type : DBG_S_C_ADVANCED_TYPE;
              Local[i++] = DBG_S_C_STRUCT_ITEM;
-             COPY_LONG (&Local[i], i2);
+             COPY_LONG (&Local[i], i2);                /* bit offset */
              i += 4;
              Local[i++] = strlen (pnt2);
              while (*pnt2 != '\0')
                Local[i++] = *pnt2++;
              VMS_Store_Immediate_Data (Local, i, OBJ_S_C_DBG);
              i = 0;
-             if (spnt1 == (struct VMS_DBG_Symbol *) NULL)
+             if (!spnt1)
                generate_suffix (spnt1, dtype);
              else if (spnt1->VMS_type == DBG_S_C_ADVANCED_TYPE)
                generate_suffix (spnt1, 0);
@@ -2609,23 +2755,23 @@ VMS_typedef_parse (str)
       spnt->struc_numb = ++structure_count;
       spnt->data_size = 4;
       VMS_Def_Struct (spnt->struc_numb);
-      fpnt = f_ref_root;
-      while (fpnt != (struct forward_ref *) NULL)
-       {
-         if (fpnt->dbx_type == spnt->dbx_type)
-           {
-             fpnt->resolved = 'Y';
-             VMS_Set_Struct (fpnt->struc_numb);
-             VMS_Store_Struct (spnt->struc_numb);
-           }
-         fpnt = fpnt->next;
-       }
-      VMS_Set_Struct (spnt->struc_numb);
       i = 0;
-      Local[i++] = 3 + strlen (symbol_name);
+      for (fpnt = f_ref_root; fpnt; fpnt = fpnt->next)
+       if (fpnt->dbx_type == spnt->dbx_type)
+         {
+           fpnt->resolved = 'Y';
+           VMS_Set_Struct (fpnt->struc_numb);
+           VMS_Store_Struct (spnt->struc_numb);
+           i++;
+         }
+      if (i > 0)
+       VMS_Set_Struct (spnt->struc_numb);
+      i = 0;
+      len = strlen (symbol_name);
+      Local[i++] = 3 + len;
       Local[i++] = DBG_S_C_ENUM_START;
-      Local[i++] = 0x20;
-      Local[i++] = strlen (symbol_name);
+      Local[i++] = 4 * 8;              /* enum values are 32 bits */
+      Local[i++] = len;
       pnt2 = symbol_name;
       while (*pnt2 != '\0')
        Local[i++] = *pnt2++;
@@ -2636,12 +2782,13 @@ VMS_typedef_parse (str)
          pnt1 = (char *) strchr (pnt, ':');
          *pnt1++ = '\0';
          pnt1 = cvt_integer (pnt1, &i1);
-         Local[i++] = 7 + strlen (pnt);
+         len = strlen (pnt);
+         Local[i++] = 7 + len;
          Local[i++] = DBG_S_C_ENUM_ITEM;
-         Local[i++] = 0x00;
+         Local[i++] = DST_K_VALKIND_LITERAL;
          COPY_LONG (&Local[i], i1);
          i += 4;
-         Local[i++] = strlen (pnt);
+         Local[i++] = len;
          pnt2 = pnt;
          while (*pnt != '\0')
            Local[i++] = *pnt++;
@@ -4399,10 +4546,10 @@ VMS_Check_For_Main ()
                       *        JSB instruction.
                       */
                      symbolP = (symbolS *) xmalloc (sizeof (*symbolP));
-                     S_GET_NAME (symbolP) = "_c$main_args";
+                     S_SET_NAME (symbolP, "_C$MAIN_ARGS");
                      S_SET_TYPE (symbolP, N_UNDF);
-                     S_GET_OTHER (symbolP) = 0;
-                     S_GET_DESC (symbolP) = 0;
+                     S_SET_OTHER (symbolP, 0);
+                     S_SET_DESC (symbolP, 0);
                      S_SET_VALUE (symbolP, 0);
                      symbolP->sy_name_offset = 0;
                      symbolP->sy_number = 0;
@@ -4577,7 +4724,7 @@ VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
        if (strncmp (S_GET_NAME (sp),"__vt.",5) == 0)
          {
            S_GET_RAW_TYPE (sp) = N_UNDF | N_EXT;
-           S_GET_OTHER (sp) = 1;
+           S_SET_OTHER (sp, 1);
            /* Is this warning still needed?  It sounds like it describes
               a compiler bug.  Does it?  If not, let's dump it.  */
            as_warn("g++ wrote an extern reference to %s as a routine.",
@@ -4619,18 +4766,11 @@ VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
          /*
           *    Make the psect for this data
           */
-         if (S_GET_OTHER (sp))
-           Globalref = VMS_Psect_Spec (
-                                        S_GET_NAME (sp),
-                                        vsp->Size,
-                                        "CONST",
-                                        vsp);
-         else
-           Globalref = VMS_Psect_Spec (
-                                        S_GET_NAME (sp),
-                                        vsp->Size,
-                                        "COMMON",
-                                        vsp);
+         Globalref = VMS_Psect_Spec (
+                                      S_GET_NAME (sp),
+                                      vsp->Size,
+                                      S_GET_OTHER (sp) ? "CONST" : "COMMON",
+                                      vsp);
          if (Globalref)
            Psect_Number--;
 
@@ -4695,18 +4835,11 @@ VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
          /*
           *    Make its psect
           */
-         if (S_GET_OTHER (sp))
-           Globalref = VMS_Psect_Spec (
-                                        S_GET_NAME (sp),
-                                        vsp->Size,
-                                        "CONST",
-                                        vsp);
-         else
-           Globalref = VMS_Psect_Spec (
-                                        S_GET_NAME (sp),
-                                        vsp->Size,
-                                        "COMMON",
-                                        vsp);
+         Globalref = VMS_Psect_Spec (
+                                      S_GET_NAME (sp),
+                                      vsp->Size,
+                                      S_GET_OTHER (sp) ? "CONST" : "COMMON",
+                                      vsp);
          if (Globalref)
            Psect_Number--;
 
@@ -5303,6 +5436,13 @@ VMS_write_object_file (text_siz, data_siz, bss_siz, text_frag_root,
                 */
                VMS_TBT_Routine_End (text_siz, Current_Routine);
              }
+           /*
+            *  Check for & skip dummy labels like "gcc_compiled.".
+            *  They're identified by the IN_DEFAULT_SECTION flag.
+            */
+           if ((S_GET_OTHER (symbolP) & IN_DEFAULT_SECTION) != 0 &&
+                     (S_GET_VALUE (symbolP) == 0))
+             continue;
            /*
             *  Store the routine begin traceback info
             */
index 8470d270b7611cd7f1d241bc8b34e2b99f2e71e9..059287cb32e825a7bc00a6a99d844e24a7fe305e 100644 (file)
@@ -1,5 +1,5 @@
 /* VMS object file format
-   Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1989, 1990, 1991, 1994 Free Software Foundation, Inc.
 
 This file is part of GAS, the GNU Assembler.
 
@@ -37,6 +37,17 @@ to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 extern char const_flag;
 
+/* This is overloaded onto const_flag, for convenience.  It's used to flag
+   dummy labels like "gcc2_compiled."  which occur before the first .text
+   or .data section directive.  */
+
+#define IN_DEFAULT_SECTION 0x80
+
+/* Compiler-generated label "__vax_g_doubles" is used to augment .stabs. */
+
+#define tc_frob_label(X) vms_check_for_special_label(X)
+extern void vms_check_for_special_label();
+
 /* These are defined in obj-vms.c. */
 extern const short seg_N_TYPE[];
 extern const segT N_TYPE_seg[];
@@ -373,7 +384,8 @@ extern int vms_resolve_symbol_redef ();
  *                                     machine-readable version seems
  *                                     to be available.
  */
-#define        DST_S_C_C               7       /* Language == "C"      */
+#define DST_S_C_C        7     /* Language == "C"      */
+#define DST_S_C_CXX     15     /* Language == "C++"    */
 #define DST_S_C_VERSION        153
 #define        DST_S_C_SOURCE  155     /* Source file          */
 #define DST_S_C_PROLOG 162
@@ -434,26 +446,73 @@ extern int vms_resolve_symbol_redef ();
 #define DBG_S_C_COMPLX8_G      0x1d            /* 2xG_float complex double */
 #define DBG_S_C_FUNCTION_ADDR  0x17
 #define DBG_S_C_ADVANCED_TYPE  0xa3
+/*  Some of these are just for future reference.  [pr]
+ */
+#define DBG_S_C_UBITA          0x01    /* unsigned, aligned bit field */
+#define DBG_S_C_UBITU          0x22    /* unsigned, unaligned bit field */
+#define DBG_S_C_SBITA          0x29    /* signed, aligned bit field */
+#define DBG_S_C_SBITU          0x2a    /* signed, unaligned bit field */
+#define DBG_S_C_CSTRING                0x2e    /* asciz ('\0' terminated) string */
+#define DBG_S_C_WCHAR          0x38    /* wchar_t */
+/*  These are descriptor class codes.
+ */
+#define DSC_K_CLASS_S          0x01    /* static (fixed length) */
+#define DSC_K_CLASS_D          0x02    /* dynamic string (not via malloc!) */
+#define DSC_K_CLASS_A          0x04    /* array */
+#define DSC_K_CLASS_UBS                0x0d    /* unaligned bit string */
 /*  These are the codes that are used to generate the definitions of struct
  *  union and enum records
  */
-#define DBG_S_C_ENUM_ITEM                      0xa4
+#define DBG_S_C_ENUM_ITEM              0xa4
 #define DBG_S_C_ENUM_START             0xa5
-#define DBG_S_C_ENUM_END                       0xa6
+#define DBG_S_C_ENUM_END               0xa6
+#define DBG_S_C_STRUCT_ITEM            DST_K_VFLAGS_BITOFFS    /* 0xff */
 #define DBG_S_C_STRUCT_START           0xab
-#define DBG_S_C_STRUCT_ITEM            0xff
 #define DBG_S_C_STRUCT_END             0xac
+#define DST_K_TYPSPEC                  0xaf            /* type specification */
+/* These codes are used in the generation of the symbol definition records
+ */
+#define DST_K_VFLAGS_NOVAL             0x80    /* struct definition only */
+#define DST_K_VFLAGS_DSC               0xfa    /* descriptor used */
+#define DST_K_VFLAGS_TVS               0xfb    /* trailing value specified */
+#define DST_K_VS_FOLLOWS               0xfd    /* value spec follows */
+#define DST_K_VFLAGS_BITOFFS           0xff    /* value contains bit offset */
+#define DST_K_VALKIND_LITERAL  0
+#define DST_K_VALKIND_ADDR     1
+#define DST_K_VALKIND_DESC     2
+#define DST_K_VALKIND_REG      3
+#define DST_K_REG_VAX_AP       0x0c    /* R12 */
+#define DST_K_REG_VAX_FP       0x0d    /* R13 */
+#define DST_K_REG_VAX_SP       0x0e    /* R14 */
+#define DST_V_VALKIND          0       /* offset of valkind field */
+#define DST_V_INDIRECT         2       /* offset to indirect bit */
+#define DST_V_DISP             3       /* offset to displacement bit */
+#define DST_V_REGNUM           4       /* offset to register number */
+#define DST_M_INDIRECT         (1<<DST_V_INDIRECT)
+#define DST_M_DISP             (1<<DST_V_DISP)
+#define DBG_C_FUNCTION_PARAM   /* 0xc9 */      \
+       (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_AP<<DST_V_REGNUM))
+#define DBG_C_LOCAL_SYM                /* 0xd9 */      \
+       (DST_K_VALKIND_ADDR|DST_M_DISP|(DST_K_REG_VAX_FP<<DST_V_REGNUM))
+/* Kinds of value specifications
+ */
+#define DST_K_VS_ALLOC_SPLIT   3       /* split lifetime */
+/* Kinds of type specifications
+ */
+#define DST_K_TS_ATOM          0x01    /* atomic type specification */
+#define DST_K_TS_DSC           0x02    /* descriptor type spec */
+#define DST_K_TS_IND           0x03    /* indirect type specification */
+#define DST_K_TS_TPTR          0x04    /* typed pointer type spec */
+#define DST_K_TS_PTR           0x05    /* pointer type spec */
+#define DST_K_TS_ARRAY         0x07    /* array type spec */
+#define DST_K_TS_NOV_LENG      0x0e    /* novel length type spec */
 /*  These are the codes that are used in the suffix records to determine the
  *  actual data type
  */
-#define DBG_S_C_BASIC                  0x01
-#define DBG_S_C_BASIC_ARRAY            0x02
-#define DBG_S_C_STRUCT                 0x03
-#define DBG_S_C_POINTER                        0x04
-#define DBG_S_C_VOID                   0x05
-#define DBG_S_C_COMPLEX_ARRAY          0x07
-/* These codes are used in the generation of the symbol definition records
- */
-#define DBG_S_C_FUNCTION_PARAMETER     0xc9
-#define DBG_S_C_LOCAL_SYM                      0xd9
+#define DBG_S_C_BASIC                  DST_K_TS_ATOM
+#define DBG_S_C_BASIC_ARRAY            DST_K_TS_DSC
+#define DBG_S_C_STRUCT                 DST_K_TS_IND
+#define DBG_S_C_POINTER                        DST_K_TS_TPTR
+#define DBG_S_C_VOID                   DST_K_TS_PTR
+#define DBG_S_C_COMPLEX_ARRAY          DST_K_TS_ARRAY
 /* end of obj-vms.h */