* read.c (read_a_source_file): If NO_PSEUDO_DOT is defined, look
[binutils-gdb.git] / gas / config / obj-coffbfd.c
index be47f48f6ff7846ccb5d6f6a3ffb2370093dae22..9a0a460a5139d5e4b194b997702bedd5bdb0a993 100644 (file)
@@ -1,5 +1,5 @@
 /* coff object file format with bfd
-   Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright (C) 1989, 1990, 1991, 1993 Free Software Foundation, Inc.
 
 This file is part of GAS.
 
@@ -68,11 +68,8 @@ const short seg_N_TYPE[] =
   9,
   10,
   C_UNDEF_SECTION,             /* SEG_UNKNOWN */
-  C_UNDEF_SECTION,             /* SEG_ABSENT */
-  C_UNDEF_SECTION,             /* SEG_PASS1 */
   C_UNDEF_SECTION,             /* SEG_GOOF */
-  C_UNDEF_SECTION,             /* SEG_BIG */
-  C_UNDEF_SECTION,             /* SEG_DIFFERENCE */
+  C_UNDEF_SECTION,             /* SEG_EXPR */
   C_DEBUG_SECTION,             /* SEG_DEBUG */
   C_NTV_SECTION,               /* SEG_NTV */
   C_PTV_SECTION,               /* SEG_PTV */
@@ -142,7 +139,7 @@ static void EXFUN( obj_coff_bss,(void));
 static void EXFUN( obj_coff_ident,(void));
 static void EXFUN (obj_coff_endef, (void));
 static void EXFUN (obj_coff_line, (void));
-static void EXFUN (obj_coff_ln, (void));
+static void EXFUN (obj_coff_ln, (int));
 static void EXFUN (obj_coff_scl, (void));
 static void EXFUN (obj_coff_size, (void));
 static void EXFUN (obj_coff_tag, (void));
@@ -163,6 +160,7 @@ const pseudo_typeS obj_pseudo_table[] =
   {"endef", obj_coff_endef, 0},
   {"line", obj_coff_line, 0},
   {"ln", obj_coff_ln, 0},
+  {"appline", obj_coff_ln, 1},
   {"scl", obj_coff_scl, 0},
   {"size", obj_coff_size, 0},
   {"tag", obj_coff_tag, 0},
@@ -177,6 +175,10 @@ const pseudo_typeS obj_pseudo_table[] =
   {"ident", obj_coff_ident, 0},
   {"ABORT", s_abort, 0},
   {"lcomm", obj_coff_lcomm, 0},
+#ifdef TC_M88K
+  /* The m88k uses sdef instead of def.  */
+  {"sdef", obj_coff_def, 0},
+#endif
   {NULL}                       /* end sentinel */
 };                             /* obj_pseudo_table */
 
@@ -359,7 +361,6 @@ DEFUN (do_relocs_for, (abfd, h, file_cursor),
          struct external_reloc *ext_ptr;
          struct external_reloc *external_reloc_vec;
          unsigned int external_reloc_size;
-         unsigned int count = 0;
          unsigned int base = segment_info[idx].scnhdr.s_paddr;
          fixS *fix_ptr = segment_info[idx].fix_root;
          nrelocs = count_entries_in_chain (idx);
@@ -395,9 +396,11 @@ DEFUN (do_relocs_for, (abfd, h, file_cursor),
                      intr.r_vaddr =
                        base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where;
 
+#ifdef TC_M88K
                      intr.r_offset = fix_ptr->fx_offset;
-
+#else
                      intr.r_offset = 0;
+#endif
 
                      /* Turn the segment of the symbol into an offset.  */
                      if (symbol_ptr)
@@ -498,7 +501,6 @@ DEFUN (fill_section, (abfd, h, file_cursor),
            }
          know (s->s_paddr == paddr);
 
-         s->s_flags = STYP_REG;
          if (strcmp (s->s_name, ".text") == 0)
            s->s_flags |= STYP_TEXT;
          else if (strcmp (s->s_name, ".data") == 0)
@@ -551,7 +553,7 @@ DEFUN (fill_section, (abfd, h, file_cursor),
                    }
 
                  fill_size = frag->fr_var;
-                 if (fill_size)
+                 if (fill_size && frag->fr_offset > 0)
                    {
                      unsigned int count;
                      unsigned int off = frag->fr_fix;
@@ -642,6 +644,7 @@ DEFUN (symbol_to_chars, (abfd, where, symbolP),
 {
   unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
   unsigned int i;
+  valueT val;
 
   /* Turn any symbols with register attributes into abs symbols */
   if (S_GET_SEGMENT (symbolP) == SEG_REGISTER)
@@ -650,9 +653,12 @@ DEFUN (symbol_to_chars, (abfd, where, symbolP),
     }
   /* At the same time, relocate all symbols to their output value */
 
-  S_SET_VALUE (symbolP,
-              segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
-              + S_GET_VALUE (symbolP));
+  val = (segment_info[S_GET_SEGMENT (symbolP)].scnhdr.s_paddr
+        + S_GET_VALUE (symbolP));
+
+  S_SET_VALUE (symbolP, val);
+
+  symbolP->sy_symbol.ost_entry.n_value = val;
 
   where += bfd_coff_swap_sym_out (abfd, &symbolP->sy_symbol.ost_entry,
                                  where);
@@ -670,8 +676,6 @@ DEFUN (symbol_to_chars, (abfd, where, symbolP),
 }
 
 
-
-
 void
 obj_symbol_new_hook (symbolP)
      symbolS *symbolP;
@@ -780,11 +784,12 @@ stack_top (st)
  */
 
 static void
-obj_coff_ln ()
+obj_coff_ln (appline)
+     int appline;
 {
   int l;
 
-  if (def_symbol_in_progress != NULL)
+  if (! appline && def_symbol_in_progress != NULL)
     {
       as_warn (".ln pseudo-op inside .def/.endef: ignored.");
       demand_empty_rest_of_line ();
@@ -801,7 +806,9 @@ obj_coff_ln ()
 
     if (listing)
       {
-       listing_source_line (l + line_base - 1);
+       if (! appline)
+         l += line_base - 1;
+       listing_source_line (l);
       }
 
   }
@@ -871,6 +878,7 @@ DEFUN (obj_coff_def, (what),
   def_symbol_in_progress->sy_name_offset = ~0;
   def_symbol_in_progress->sy_number = ~0;
   def_symbol_in_progress->sy_frag = &zero_address_frag;
+  S_SET_VALUE (def_symbol_in_progress, 0);
 
   if (S_IS_STRING (def_symbol_in_progress))
     {
@@ -962,55 +970,47 @@ DEFUN_VOID (obj_coff_endef)
       break;
     }                          /* switch on storage class */
 
-  /* Now that we have built a debug symbol, try to find if
-       we should merge with an existing symbol or not.  If a
-       symbol is C_EFCN or SEG_ABSOLUTE or untagged
-       SEG_DEBUG it never merges.  We also don't merge
-       labels, which are in a different namespace, nor
-       symbols which have not yet been defined since they
-       are typically unique, nor do we merge tags with
-       non-tags.  */
-
-  /* Two cases for functions.  Either debug followed
-       by definition or definition followed by debug.
-       For definition first, we will merge the debug
-       symbol into the definition.  For debug first, the
-       lineno entry MUST point to the definition
-       function or else it will point off into space
-       when crawl_symbols() merges the debug
-       symbol into the real symbol.  Therefor, let's
-       presume the debug symbol is a real function
-       reference. */
-
-  /* FIXME-SOON If for some reason the definition
-       label/symbol is never seen, this will probably
-       leave an undefined symbol at link time. */
+  /* Now that we have built a debug symbol, try to find if we should
+     merge with an existing symbol or not.  If a symbol is C_EFCN or
+     SEG_ABSOLUTE or untagged SEG_DEBUG it never merges.  We also
+     don't merge labels, which are in a different namespace, nor
+     symbols which have not yet been defined since they are typically
+     unique, nor do we merge tags with non-tags.  */
+
+  /* Two cases for functions.  Either debug followed by definition or
+     definition followed by debug.  For definition first, we will
+     merge the debug symbol into the definition.  For debug first, the
+     lineno entry MUST point to the definition function or else it
+     will point off into space when crawl_symbols() merges the debug
+     symbol into the real symbol.  Therefor, let's presume the debug
+     symbol is a real function reference. */
+
+  /* FIXME-SOON If for some reason the definition label/symbol is
+     never seen, this will probably leave an undefined symbol at link
+     time. */
 
   if (S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_EFCN
       || S_GET_STORAGE_CLASS (def_symbol_in_progress) == C_LABEL
       || (S_GET_SEGMENT (def_symbol_in_progress) == SEG_DEBUG
          && !SF_GET_TAG (def_symbol_in_progress))
       || S_GET_SEGMENT (def_symbol_in_progress) == SEG_ABSOLUTE
-      || def_symbol_in_progress->sy_forward != NULL
+      || def_symbol_in_progress->sy_value.X_op != O_constant
       || (symbolP = symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP)) == NULL
       || (SF_GET_TAG (def_symbol_in_progress) != SF_GET_TAG (symbolP)))
     {
-
-      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
-
+      symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP,
+                    &symbol_lastP);
     }
   else
     {
-      /* This symbol already exists, merge the
-                  newly created symbol into the old one.
-                  This is not mandatory. The linker can
-                  handle duplicate symbols correctly. But I
-                  guess that it save a *lot* of space if
-                  the assembly file defines a lot of
-                  symbols. [loic] */
+      /* This symbol already exists, merge the newly created symbol
+        into the This is not mandatory. The linker can handle
+        duplicate symbols correctly. But I guess that it save a *lot*
+        of space if the assembly file defines a lot of
+        symbols. [loic] */
 
-      /* The debug entry (def_symbol_in_progress)
-                  is merged into the previous definition. */
+      /* The debug entry (def_symbol_in_progress) is merged into the
+        previous definition.  */
 
       c_symbol_merge (def_symbol_in_progress, symbolP);
       /* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
@@ -1019,13 +1019,16 @@ DEFUN_VOID (obj_coff_endef)
       if (SF_GET_FUNCTION (def_symbol_in_progress)
          || SF_GET_TAG (def_symbol_in_progress))
        {
-         /* For functions, and tags, the symbol *must* be where the debug symbol
-                          appears.  Move the existing symbol to the current place. */
+         /* For functions, and tags, the symbol *must* be where the
+            debug symbol appears.  Move the existing symbol to the
+            current place. */
          /* If it already is at the end of the symbol list, do nothing */
          if (def_symbol_in_progress != symbol_lastP)
            {
-             symbol_remove (def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
-             symbol_append (def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+             symbol_remove (def_symbol_in_progress, &symbol_rootP,
+                            &symbol_lastP);
+             symbol_append (def_symbol_in_progress, symbol_lastP,
+                            &symbol_rootP, &symbol_lastP);
            }                   /* if not already in place */
        }                       /* if function */
     }                          /* normal or mergable */
@@ -1034,7 +1037,7 @@ DEFUN_VOID (obj_coff_endef)
       && symbol_find_base (S_GET_NAME (def_symbol_in_progress), DO_NOT_STRIP) == NULL)
     {
       tag_insert (S_GET_NAME (def_symbol_in_progress), def_symbol_in_progress);
-    }                          /* If symbol is a {structure,union} tag, associate symbol to its name. */
+    }
 
   if (SF_GET_FUNCTION (def_symbol_in_progress))
     {
@@ -1042,14 +1045,12 @@ DEFUN_VOID (obj_coff_endef)
       function_lineoff
        = c_line_new (def_symbol_in_progress, 0, 0, &zero_address_frag);
 
-
-
       SF_SET_PROCESS (def_symbol_in_progress);
 
       if (symbolP == NULL)
        {
-         /* That is, if this is the first
-                      time we've seen the function... */
+         /* That is, if this is the first time we've seen the
+            function... */
          symbol_table_insert (def_symbol_in_progress);
        }                       /* definition follows debug */
     }                          /* Create the line number entry pointing to the function being defined */
@@ -1057,7 +1058,7 @@ DEFUN_VOID (obj_coff_endef)
   def_symbol_in_progress = NULL;
   demand_empty_rest_of_line ();
   return;
-}                              /* obj_coff_endef() */
+}
 
 static void
 DEFUN_VOID (obj_coff_dim)
@@ -1106,7 +1107,7 @@ obj_coff_line ()
 
   if (def_symbol_in_progress == NULL)
     {
-      obj_coff_ln ();
+      obj_coff_ln (0);
       return;
     }                          /* if it looks like a stabs style line */
 
@@ -1241,11 +1242,15 @@ obj_coff_val ()
        }
       else if (strcmp (S_GET_NAME (def_symbol_in_progress), symbol_name))
        {
-         def_symbol_in_progress->sy_forward = symbol_find_or_make (symbol_name);
-
-         /* If the segment is undefined when the forward
-                          reference is solved, then copy the segment id
-                          from the forward symbol. */
+         def_symbol_in_progress->sy_value.X_op = O_symbol;
+         def_symbol_in_progress->sy_value.X_add_symbol =
+           symbol_find_or_make (symbol_name);
+         def_symbol_in_progress->sy_value.X_op_symbol = NULL;
+         def_symbol_in_progress->sy_value.X_add_number = 0;
+
+         /* If the segment is undefined when the forward reference is
+            resolved, then copy the segment id from the forward
+            symbol.  */
          SF_SET_GET_SEGMENT (def_symbol_in_progress);
 
          /* FIXME: gcc can generate address expressions
@@ -1372,6 +1377,7 @@ DEFUN_VOID (yank_symbols)
          /* L* and C_EFCN symbols never merge. */
          if (!SF_GET_LOCAL (symbolP)
              && S_GET_STORAGE_CLASS (symbolP) != C_LABEL
+             && symbolP->sy_value.X_op == O_constant
              && (real_symbolP = symbol_find_base (S_GET_NAME (symbolP), DO_NOT_STRIP))
              && real_symbolP != symbolP)
            {
@@ -1398,8 +1404,7 @@ DEFUN_VOID (yank_symbols)
              S_SET_SEGMENT (symbolP, SEG_E0);
            }                   /* push data into text */
 
-         S_SET_VALUE (symbolP,
-                      S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address);
+         resolve_symbol_value (symbolP);
 
          if (!S_IS_DEFINED (symbolP) && !SF_GET_LOCAL (symbolP))
            {
@@ -1609,35 +1614,11 @@ DEFUN (crawl_symbols, (h, abfd),
 {
 
   unsigned int i;
-  unsigned int ptr = 0;
-
-
   symbolS *symbolP;
 
   /* Initialize the stack used to keep track of the matching .bb .be */
 
   block_stack = stack_init (512, sizeof (symbolS *));
-  /* JF deal with forward references first... */
-  for (symbolP = symbol_rootP;
-       symbolP;
-       symbolP = symbol_next (symbolP))
-    {
-
-      if (symbolP->sy_forward)
-       {
-         S_SET_VALUE (symbolP, (S_GET_VALUE (symbolP)
-                                + S_GET_VALUE (symbolP->sy_forward)
-                              + symbolP->sy_forward->sy_frag->fr_address));
-
-         if (SF_GET_GET_SEGMENT (symbolP))
-           {
-             S_SET_SEGMENT (symbolP, S_GET_SEGMENT (symbolP->sy_forward));
-           }                   /* forward segment also */
-
-         symbolP->sy_forward = 0;
-       }                       /* if it has a forward reference */
-    }                          /* walk the symbol chain */
-
 
   /* The symbol list should be ordered according to the following sequence
    * order :
@@ -1698,8 +1679,8 @@ DEFUN (w_strings, (where),
   symbolS *symbolP;
 
   /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
-  md_number_to_chars (where, string_byte_count, sizeof (string_byte_count));
-  where += sizeof (string_byte_count);
+  md_number_to_chars (where, string_byte_count, 4);
+  where += 4;
   for (symbolP = symbol_rootP;
        symbolP;
        symbolP = symbol_next (symbolP))
@@ -1962,11 +1943,11 @@ DEFUN (change_to_section, (name, len, exp),
        {
          subseg_new (i, exp);
          return;
-
        }
     }
   /* No section, add one */
   strncpy (segment_info[i].scnhdr.s_name, name, 8);
+  segment_info[i].scnhdr.s_flags = STYP_REG;
   subseg_new (i, exp);
 }
 
@@ -2066,7 +2047,10 @@ obj_coff_text ()
 static void
 obj_coff_data ()
 {
-  change_to_section (".data", 5, get_absolute_expression ());
+  if (flagseen['R'])
+    change_to_section (".text", 5, get_absolute_expression () + 1000);
+  else
+    change_to_section (".data", 5, get_absolute_expression ());
 }
 
 static void
@@ -2548,7 +2532,11 @@ DEFUN (fixup_segment, (segP, this_segment_type),
 
       if (pcrel)
        {
+#ifndef TC_M88K
+         /* This adjustment is not correct on the m88k, for which the
+            linker does all the computation.  */
          add_number -= md_pcrel_from (fixP);
+#endif
          if (add_symbolP == 0)
            {
              fixP->fx_addsy = &abs_symbol;
@@ -2562,6 +2550,9 @@ DEFUN (fixup_segment, (segP, this_segment_type),
 
       if (!fixP->fx_bit_fixP)
        {
+#ifndef TC_M88K
+         /* The m88k uses the offset field of the reloc to get around
+            this problem.  */
          if ((size == 1 &&
          (add_number & ~0xFF) && ((add_number & ~0xFF) != (-1 & ~0xFF))) ||
              (size == 2 &&
@@ -2570,6 +2561,7 @@ DEFUN (fixup_segment, (segP, this_segment_type),
              as_bad ("Value of %d too large for field of %d bytes at 0x%x",
                      add_number, size, fragP->fr_address + where);
            }                   /* generic error checking */
+#endif
 #ifdef WARN_SIGNED_OVERFLOW_WORD
          /* Warn if a .word value is too large when treated as
             a signed number.  We already know it is not too