diff --git a/gas/ChangeLog b/gas/ChangeLog
index c95545df1d6..86525d1814b 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+Sun Mar 16 13:49:21 1997  Ian Lance Taylor  <ian@cygnus.com>
+
+	* symbols.c (symbol_new): Don't call debug_verify_symchain.
+	(symbol_append): Set sy_next and sy_previous when adding a single
+	symbol to an empty list.  Call debug_verify_symchain.
+	(verify_symbol_chain): Use assert, not know.
+
 Sat Mar 15 20:27:12 1997  Fred Fish  <fnf@cygnus.com>
 
 	* NEWS: Note BeOS support.
diff --git a/gas/symbols.c b/gas/symbols.c
index def3f6be537..7d3fa1576ba 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -1,5 +1,5 @@
 /* symbols.c -symbol table-
-   Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -15,8 +15,9 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   along with GAS; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
 
 /* #define DEBUG_SYMS / * to debug symbol list maintenance */
 
@@ -84,7 +85,6 @@ symbol_new (name, segment, valu, frag)
   }
 #endif
   symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
-  debug_verify_symchain (symbol_rootP, symbol_lastP);
 
   return symbolP;
 }
@@ -173,8 +173,19 @@ colon (sym_name)		/* just seen "x:" - rattle symbols & frags */
 
   /* Sun local labels go out of scope whenever a non-local symbol is
      defined.  */
-  if (LOCAL_LABELS_DOLLAR && ! LOCAL_LABEL (sym_name))
-    dollar_label_clear ();
+  if (LOCAL_LABELS_DOLLAR)
+    {
+      int local;
+
+#ifdef BFD_ASSEMBLER
+      local = bfd_is_local_label_name (stdoutput, sym_name);
+#else
+      local = LOCAL_LABEL (sym_name);
+#endif
+
+      if (! local)
+	dollar_label_clear ();
+    }
 
 #ifndef WORKING_DOT_WORD
   if (new_broken_words)
@@ -479,6 +490,10 @@ symbol_append (addme, target, rootPP, lastPP)
     {
       know (*rootPP == NULL);
       know (*lastPP == NULL);
+      addme->sy_next = NULL;
+#ifdef SYMBOLS_NEED_BACKPOINTERS
+      addme->sy_previous = NULL;
+#endif
       *rootPP = addme;
       *lastPP = addme;
       return;
@@ -502,6 +517,8 @@ symbol_append (addme, target, rootPP, lastPP)
 #ifdef SYMBOLS_NEED_BACKPOINTERS
   addme->sy_previous = target;
 #endif /* SYMBOLS_NEED_BACKPOINTERS */
+
+  debug_verify_symchain (symbol_rootP, symbol_lastP);
 }
 
 /* Set the chain pointers of SYMBOL to null. */
@@ -586,7 +603,7 @@ verify_symbol_chain (rootP, lastP)
   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
     {
 #ifdef SYMBOLS_NEED_BACKPOINTERS
-      know (symbolP->sy_next->sy_previous == symbolP);
+      assert (symbolP->sy_next->sy_previous == symbolP);
 #else
       /* Walk the list anyways, to make sure pointers are still good.  */
       ;
@@ -704,7 +721,11 @@ resolve_symbol_value (symp)
              is equated.  */
 	  if (! S_IS_DEFINED (symp->sy_value.X_add_symbol)
 	      || S_IS_COMMON (symp->sy_value.X_add_symbol))
-	    symp->sy_value.X_op = O_symbol;
+	    {
+	      symp->sy_value.X_op = O_symbol;
+	      S_SET_SEGMENT (symp,
+			     S_GET_SEGMENT (symp->sy_value.X_add_symbol));
+	    }
 	  else
 	    {
 	      S_SET_VALUE (symp,
@@ -782,26 +803,30 @@ resolve_symbol_value (symp)
 
 	      if (expr_symbol_where (symp, &file, &line))
 		{
-		  if (seg_left == undefined_section
-		      || seg_right == undefined_section)
+		  if (seg_left == undefined_section)
 		    as_bad_where (file, line,
 				  "undefined symbol %s in operation",
-				  (seg_left == undefined_section
-				   ? S_GET_NAME (symp->sy_value.X_add_symbol)
-				   : S_GET_NAME (symp->sy_value.X_op_symbol)));
-		  else
+				  S_GET_NAME (symp->sy_value.X_add_symbol));
+		  if (seg_right == undefined_section)
+		    as_bad_where (file, line,
+				  "undefined symbol %s in operation",
+				  S_GET_NAME (symp->sy_value.X_op_symbol));
+		  if (seg_left != undefined_section
+		      && seg_right != undefined_section)
 		    as_bad_where (file, line, "invalid section for operation");
 		}
 	      else
 		{
-		  if (seg_left == undefined_section
-		      || seg_right == undefined_section)
+		  if (seg_left == undefined_section)
 		    as_bad ("undefined symbol %s in operation setting %s",
-			    (seg_left == undefined_section
-			     ? S_GET_NAME (symp->sy_value.X_add_symbol)
-			     : S_GET_NAME (symp->sy_value.X_op_symbol)),
+			    S_GET_NAME (symp->sy_value.X_add_symbol),
 			    S_GET_NAME (symp));
-		  else
+		  if (seg_right == undefined_section)
+		    as_bad ("undefined symbol %s in operation setting %s",
+			    S_GET_NAME (symp->sy_value.X_op_symbol),
+			    S_GET_NAME (symp));
+		  if (seg_left != undefined_section
+		      && seg_right != undefined_section)
 		    as_bad ("invalid section for operation setting %s",
 			    S_GET_NAME (symp));
 		}
@@ -1343,7 +1368,7 @@ S_IS_LOCAL (s)
 	  && (strchr (name, '\001')
 	      || strchr (name, '\002')
 	      || (! flag_keep_locals
-		  && (LOCAL_LABEL (name)
+		  && (bfd_is_local_label (stdoutput, s->bsym)
 		      || (flag_mri
 			  && name[0] == '?'
 			  && name[1] == '?')))));