Bug 3303

Summary: wrong assembly when using division in expression
Product: Sisyphus Reporter: Sergey Vlasov <vsu>
Component: binutilsAssignee: Gleb F-Malinovskiy <glebfm>
Status: CLOSED FIXED QA Contact: qa-sisyphus
Severity: normal    
Priority: P2 CC: glebfm
Version: unstable   
Hardware: all   
OS: Linux   

Description Sergey Vlasov 2003-11-22 13:31:21 MSK
gas has a bug which leads to miscompilation of recent 2.6 kernels (seems to not
hit 2.4.x in this particular place - however, there might be similar code in
other places).

Tried to compile the test code below with binutils-2.14.90.0.6-alt1 - this
version has the bug.

Date:                 Sat, 22 Nov 2003 15:12:21 +1030
From:                 Alan Modra <>
In-Reply-To:          <Pine.LNX.4.44.0311211455510.13789-100000@home.osdl.org>
Lines:                101
Message-ID:           <20031122044221.GN2900@bubble.sa.bigpond.net.au>
Newsgroups:           gmane.linux.kernel
Subject:              Re: ionice kills vanilla 2.6.0-test9 was [Re: [PATCH]
cfq + io	priorities (fwd)]

On Fri, Nov 21, 2003 at 03:05:23PM -0800, Linus Torvalds wrote:
> So it definitely _does_ work in some versions, and the bug appears to be 
> new to binutils 2.14, with 2.13 doing the right thing.
> 
> You can trivially see if with a simple assembly file like
> 
> 	start:
> 		.long 1,2,3,a
> 	a=(.-start)/4

Broken with http://sources.redhat.com/ml/binutils/2003-04/msg00412.html
and http://sources.redhat.com/ml/binutils/2003-04/msg00414.html.
That '/' is being treated as a start of line comment char, thus trimming
the rest of the line.

I think gas/app.c:do_scrub_chars is such an awful mess that it's
impossible to get right.  Needs to be tossed out and rewritten.  The
fundamental problem is that you can't track which component of an
assember input line you're preprocessing without more information on the
particular target syntax.  And most of the current complexity is just
for deciding whether to remove whitespace!  That at least needs to go.

For now, I'm reverting HJ's patches and including your testcase in
the gas testsuite.

gas/ChangeLog
	* app.c (do_scrub_chars): Revert 2003-04-23 and 2003-04-22.

gas/testsuite/ChangeLog
	* gas/i386/divide.s: New.
	* gas/i386/divide.d: New.
	* gas/i386/i386.exp (gas_32_check): Run it.

Index: app.c
===================================================================
RCS file: /cvs/src/src/gas/app.c,v
retrieving revision 1.26
diff -u -p -r1.26 app.c
--- app.c	21 Nov 2003 01:52:16 -0000	1.26
+++ app.c	22 Nov 2003 04:24:01 -0000
@@ -1308,13 +1308,11 @@ do_scrub_chars (int (*get) (char *, int)
 	  /* Some relatively `normal' character.  */
 	  if (state == 0)
 	    {
-	      if (IS_SYMBOL_COMPONENT (ch))
-		state = 11;	/* Now seeing label definition.  */
+	      state = 11;	/* Now seeing label definition.  */
 	    }
 	  else if (state == 1)
 	    {
-	      if (IS_SYMBOL_COMPONENT (ch))
-		state = 2;	/* Ditto.  */
+	      state = 2;	/* Ditto.  */
 	    }
 	  else if (state == 9)
 	    {
Index: testsuite/gas/i386/divide.d
===================================================================
RCS file: testsuite/gas/i386/divide.d
diff -N testsuite/gas/i386/divide.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/i386/divide.d	22 Nov 2003 04:41:09 -0000
@@ -0,0 +1,8 @@
+#objdump: -s
+#name: i386 divide
+
+.*: +file format .*
+
+Contents of section .*
+ 0000 01000000 02000000 03000000 04000000 .*
+ 0010 05000000 .*
Index: testsuite/gas/i386/divide.s
===================================================================
RCS file: testsuite/gas/i386/divide.s
diff -N testsuite/gas/i386/divide.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/i386/divide.s	22 Nov 2003 04:41:09 -0000
@@ -0,0 +1,4 @@
+start:
+ .long 1,2,3,a,b
+ a=(.-start)/4-1
+b=(.-start)/4
Index: testsuite/gas/i386/i386.exp
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/i386/i386.exp,v
retrieving revision 1.19
diff -u -p -r1.19 i386.exp
--- testsuite/gas/i386/i386.exp	23 Jun 2003 20:15:33 -0000	1.19
+++ testsuite/gas/i386/i386.exp	22 Nov 2003 04:41:09 -0000
@@ -57,6 +57,7 @@ if [expr ([istarget "i*86-*-*"] ||  [ist
     run_dump_test "pcrel"
     run_dump_test "sub"
     run_dump_test "prescott"
+    run_dump_test "divide"
 
     # PIC is only supported on ELF targets.
     if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"] )

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre
Comment 1 Dmitry V. Levin 2004-01-11 02:16:06 MSK
Fixed in 2.14.90.0.6-alt3