This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] GAS: Fix bogus "attempt to move .org backwards" relaxation errors


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9875b36538d35f2292ddc3bb5e7c60e1582aa087

commit 9875b36538d35f2292ddc3bb5e7c60e1582aa087
Author: Maciej W. Rozycki <macro@imgtec.com>
Date:   Thu Mar 2 01:24:15 2017 +0000

    GAS: Fix bogus "attempt to move .org backwards" relaxation errors
    
    Fix a commit 6afe8e98a664 ("internal error for backwards .org"),
    <https://www.sourceware.org/ml/binutils/2008-06/msg00212.html>,
    GAS regression that caused legitimate code to fail assembly with an
    "attempt to move .org backwards" error.
    
    For example with the `mips-linux' target we get:
    
    $ cat org.s
    	.set	mips16
    	la	$2, foo
    	.org	0x1000
    	.align	2
    foo:
    	.half	0
    $ as -o org.o org.s
    org.s: Assembler messages:
    org.s:3: Error: attempt to move .org backwards
    $
    
    where the location pointer is obviously not moved backwards with `.org'.
    
    The cause is positive `stretch' in relaxation due to a PC-relative ADDIU
    instruction (produced from the LA macro used) getting expanded from 2 to
    4 bytes as `foo' is noticed to be out of range for the short encoding.
    This in turn triggers logic in `relax_segment' which concludes in the
    processing of an `rs_org' frag produced that the location pointer is
    moved backwards while in fact only the amount to space forward to the
    location requested has shrunk, resulting in a negative growth of the
    frag.
    
    Correct the bad logic then and instead verify that the fixed part of an
    `rs_org' frag has not overrun the location requested, as per the comment
    already included with the error message:
    
    /* Growth may be negative, but variable part of frag
       cannot have fewer than 0 chars.  That is, we can't
       .org backwards.  */
    
    which accurately describes the regression scenario.  Move the comment
    ahead the conditional noted, for clarity.
    
    Add generic and MIPS test cases for the `.org' pseudo-op, including the
    test case discussed though not integrated with the offending commit in
    particular, adjusted to work across all targets.
    
    	gas/
    	* write.c (relax_segment) <rs_org>: Only bail out if the fixed
    	part of the frag has overrun the location requested.
    
    	* testsuite/gas/all/org-1.d: New test.
    	* testsuite/gas/all/org-2.d: New test.
    	* testsuite/gas/all/org-3.d: New test.
    	* testsuite/gas/all/org-4.d: New test.
    	* testsuite/gas/all/org-5.d: New test.
    	* testsuite/gas/all/org-6.d: New test.
    	* testsuite/gas/all/org-1.l: New stderr output.
    	* testsuite/gas/all/org-2.l: New stderr output.
    	* testsuite/gas/all/org-3.l: New stderr output.
    	* testsuite/gas/all/org-1.s: New test source.
    	* testsuite/gas/all/org-2.s: New test source.
    	* testsuite/gas/all/org-3.s: New test source.
    	* testsuite/gas/all/org-4.s: New test source.
    	* testsuite/gas/all/org-5.s: New test source.
    	* testsuite/gas/all/org-6.s: New test source.
    	* testsuite/gas/all/gas.exp: Run the new tests.
    
    	* testsuite/gas/mips/org-1.d: New test.
    	* testsuite/gas/mips/org-2.d: New test.
    	* testsuite/gas/mips/org-3.d: New test.
    	* testsuite/gas/mips/org-4.d: New test.
    	* testsuite/gas/mips/org-5.d: New test.
    	* testsuite/gas/mips/org-6.d: New test.
    	* testsuite/gas/mips/org-7.d: New test.
    	* testsuite/gas/mips/org-8.d: New test.
    	* testsuite/gas/mips/org-9.d: New test.
    	* testsuite/gas/mips/org-10.d: New test.
    	* testsuite/gas/mips/org-11.d: New test.
    	* testsuite/gas/mips/org-12.d: New test.
    	* testsuite/gas/mips/org-1.l: New stderr output.
    	* testsuite/gas/mips/org-4.l: New stderr output.
    	* testsuite/gas/mips/org-5.l: New stderr output.
    	* testsuite/gas/mips/org-6.l: New stderr output.
    	* testsuite/gas/mips/org-10.l: New stderr output.
    	* testsuite/gas/mips/org-1.s: New test source.
    	* testsuite/gas/mips/org-2.s: New test source.
    	* testsuite/gas/mips/org-3.s: New test source.
    	* testsuite/gas/mips/org-4.s: New test source.
    	* testsuite/gas/mips/org-5.s: New test source.
    	* testsuite/gas/mips/org-6.s: New test source.
    	* testsuite/gas/mips/org-7.s: New test source.
    	* testsuite/gas/mips/org-8.s: New test source.
    	* testsuite/gas/mips/org-9.s: New test source.
    	* testsuite/gas/mips/org-10.s: New test source.
    	* testsuite/gas/mips/org-11.s: New test source.
    	* testsuite/gas/mips/org-12.s: New test source.
    	* testsuite/gas/mips/mips.exp: Run the new tests.

Diff:
---
 gas/ChangeLog                   | 53 +++++++++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/all/gas.exp   | 28 ++++++++++++++++++++++
 gas/testsuite/gas/all/org-1.d   |  3 +++
 gas/testsuite/gas/all/org-1.l   |  2 ++
 gas/testsuite/gas/all/org-1.s   | 25 +++++++++++++++++++
 gas/testsuite/gas/all/org-2.d   |  2 ++
 gas/testsuite/gas/all/org-2.l   |  2 ++
 gas/testsuite/gas/all/org-2.s   |  9 +++++++
 gas/testsuite/gas/all/org-3.d   |  2 ++
 gas/testsuite/gas/all/org-3.l   |  2 ++
 gas/testsuite/gas/all/org-3.s   |  9 +++++++
 gas/testsuite/gas/all/org-4.d   |  5 ++++
 gas/testsuite/gas/all/org-4.s   |  9 +++++++
 gas/testsuite/gas/all/org-5.d   |  5 ++++
 gas/testsuite/gas/all/org-5.s   |  9 +++++++
 gas/testsuite/gas/all/org-6.d   |  5 ++++
 gas/testsuite/gas/all/org-6.s   |  9 +++++++
 gas/testsuite/gas/mips/mips.exp | 13 ++++++++++
 gas/testsuite/gas/mips/org-1.d  |  7 ++++++
 gas/testsuite/gas/mips/org-1.l  |  2 ++
 gas/testsuite/gas/mips/org-1.s  |  9 +++++++
 gas/testsuite/gas/mips/org-10.d |  7 ++++++
 gas/testsuite/gas/mips/org-10.l |  2 ++
 gas/testsuite/gas/mips/org-10.s | 11 +++++++++
 gas/testsuite/gas/mips/org-11.d |  6 +++++
 gas/testsuite/gas/mips/org-11.s | 13 ++++++++++
 gas/testsuite/gas/mips/org-12.d |  5 ++++
 gas/testsuite/gas/mips/org-12.s | 13 ++++++++++
 gas/testsuite/gas/mips/org-2.d  |  6 +++++
 gas/testsuite/gas/mips/org-2.s  | 11 +++++++++
 gas/testsuite/gas/mips/org-3.d  |  5 ++++
 gas/testsuite/gas/mips/org-3.s  | 11 +++++++++
 gas/testsuite/gas/mips/org-4.d  |  3 +++
 gas/testsuite/gas/mips/org-4.l  |  3 +++
 gas/testsuite/gas/mips/org-4.s  | 11 +++++++++
 gas/testsuite/gas/mips/org-5.d  |  3 +++
 gas/testsuite/gas/mips/org-5.l  |  2 ++
 gas/testsuite/gas/mips/org-5.s  | 13 ++++++++++
 gas/testsuite/gas/mips/org-6.d  |  2 ++
 gas/testsuite/gas/mips/org-6.l  |  2 ++
 gas/testsuite/gas/mips/org-6.s  | 13 ++++++++++
 gas/testsuite/gas/mips/org-7.d  |  6 +++++
 gas/testsuite/gas/mips/org-7.s  | 11 +++++++++
 gas/testsuite/gas/mips/org-8.d  |  6 +++++
 gas/testsuite/gas/mips/org-8.s  | 13 ++++++++++
 gas/testsuite/gas/mips/org-9.d  |  5 ++++
 gas/testsuite/gas/mips/org-9.s  | 13 ++++++++++
 gas/write.c                     |  9 +++----
 48 files changed, 411 insertions(+), 4 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 9be9530..785f9a4 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,56 @@
+2017-03-02  Maciej W. Rozycki  <macro@imgtec.com>
+
+	* write.c (relax_segment) <rs_org>: Only bail out if the fixed
+	part of the frag has overrun the location requested.
+
+	* testsuite/gas/all/org-1.d: New test.
+	* testsuite/gas/all/org-2.d: New test.
+	* testsuite/gas/all/org-3.d: New test.
+	* testsuite/gas/all/org-4.d: New test.
+	* testsuite/gas/all/org-5.d: New test.
+	* testsuite/gas/all/org-6.d: New test.
+	* testsuite/gas/all/org-1.l: New stderr output.
+	* testsuite/gas/all/org-2.l: New stderr output.
+	* testsuite/gas/all/org-3.l: New stderr output.
+	* testsuite/gas/all/org-1.s: New test source.
+	* testsuite/gas/all/org-2.s: New test source.
+	* testsuite/gas/all/org-3.s: New test source.
+	* testsuite/gas/all/org-4.s: New test source.
+	* testsuite/gas/all/org-5.s: New test source.
+	* testsuite/gas/all/org-6.s: New test source.
+	* testsuite/gas/all/gas.exp: Run the new tests.
+
+	* testsuite/gas/mips/org-1.d: New test.
+	* testsuite/gas/mips/org-2.d: New test.
+	* testsuite/gas/mips/org-3.d: New test.
+	* testsuite/gas/mips/org-4.d: New test.
+	* testsuite/gas/mips/org-5.d: New test.
+	* testsuite/gas/mips/org-6.d: New test.
+	* testsuite/gas/mips/org-7.d: New test.
+	* testsuite/gas/mips/org-8.d: New test.
+	* testsuite/gas/mips/org-9.d: New test.
+	* testsuite/gas/mips/org-10.d: New test.
+	* testsuite/gas/mips/org-11.d: New test.
+	* testsuite/gas/mips/org-12.d: New test.
+	* testsuite/gas/mips/org-1.l: New stderr output.
+	* testsuite/gas/mips/org-4.l: New stderr output.
+	* testsuite/gas/mips/org-5.l: New stderr output.
+	* testsuite/gas/mips/org-6.l: New stderr output.
+	* testsuite/gas/mips/org-10.l: New stderr output.
+	* testsuite/gas/mips/org-1.s: New test source.
+	* testsuite/gas/mips/org-2.s: New test source.
+	* testsuite/gas/mips/org-3.s: New test source.
+	* testsuite/gas/mips/org-4.s: New test source.
+	* testsuite/gas/mips/org-5.s: New test source.
+	* testsuite/gas/mips/org-6.s: New test source.
+	* testsuite/gas/mips/org-7.s: New test source.
+	* testsuite/gas/mips/org-8.s: New test source.
+	* testsuite/gas/mips/org-9.s: New test source.
+	* testsuite/gas/mips/org-10.s: New test source.
+	* testsuite/gas/mips/org-11.s: New test source.
+	* testsuite/gas/mips/org-12.s: New test source.
+	* testsuite/gas/mips/mips.exp: Run the new tests.
+
 2017-03-01  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
 	* doc/c-aarch64.texi (AArch64 Extensions): Document rcpc.
diff --git a/gas/testsuite/gas/all/gas.exp b/gas/testsuite/gas/all/gas.exp
index 009e68c..b5b0beb 100644
--- a/gas/testsuite/gas/all/gas.exp
+++ b/gas/testsuite/gas/all/gas.exp
@@ -455,3 +455,31 @@ load_lib gas-dg.exp
 dg-init
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" ""
 dg-finish
+
+# Set $nop_type appropriately to indicate the NOP instruction mnemonic.
+case $target_triplet in {
+    { "mmix-*-*" } {
+	set nop_type 5
+    }
+    { "i960-*-*" } {
+	set nop_type 4
+    }
+    { "i370-*-*" } {
+	set nop_type 3
+    }
+    { "or1k*-*-*" } {
+	set nop_type 2
+    }
+    { "ia64-*-*" } {
+	set nop_type 1
+    }
+    default {
+	set nop_type 0
+    }
+}
+run_dump_test "org-1" [list [list as "--defsym nop_type=$nop_type"]]
+run_dump_test "org-2"
+run_dump_test "org-3"
+run_dump_test "org-4"
+run_dump_test "org-5"
+run_dump_test "org-6"
diff --git a/gas/testsuite/gas/all/org-1.d b/gas/testsuite/gas/all/org-1.d
new file mode 100644
index 0000000..983e6d6
--- /dev/null
+++ b/gas/testsuite/gas/all/org-1.d
@@ -0,0 +1,3 @@
+#name: .org test 1
+#as: -gdwarf2
+#error-output: org-1.l
diff --git a/gas/testsuite/gas/all/org-1.l b/gas/testsuite/gas/all/org-1.l
new file mode 100644
index 0000000..79932c0
--- /dev/null
+++ b/gas/testsuite/gas/all/org-1.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:22: Error: attempt to move \.org backwards
diff --git a/gas/testsuite/gas/all/org-1.s b/gas/testsuite/gas/all/org-1.s
new file mode 100644
index 0000000..4d7b12b
--- /dev/null
+++ b/gas/testsuite/gas/all/org-1.s
@@ -0,0 +1,25 @@
+	.macro	i_nop
+	.if	nop_type == 1
+	nop	0
+	.elseif	nop_type == 2
+	l.nop
+	.elseif	nop_type == 3
+	nopr	1
+	.elseif	nop_type == 4
+	mov	g0, g0
+	.elseif	nop_type == 5
+	set	$0, $0
+	.else
+	nop
+	.endif
+	.endm
+
+	.text
+	.org	0x20
+	.globl	foo
+foo:
+	i_nop
+	.org	0x10
+	.globl	bar
+bar:
+	i_nop
diff --git a/gas/testsuite/gas/all/org-2.d b/gas/testsuite/gas/all/org-2.d
new file mode 100644
index 0000000..6295a97
--- /dev/null
+++ b/gas/testsuite/gas/all/org-2.d
@@ -0,0 +1,2 @@
+#name: .org test 2
+#error-output: org-2.l
diff --git a/gas/testsuite/gas/all/org-2.l b/gas/testsuite/gas/all/org-2.l
new file mode 100644
index 0000000..2995bb0
--- /dev/null
+++ b/gas/testsuite/gas/all/org-2.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:6: Error: attempt to move \.org backwards
diff --git a/gas/testsuite/gas/all/org-2.s b/gas/testsuite/gas/all/org-2.s
new file mode 100644
index 0000000..4eb0d1f
--- /dev/null
+++ b/gas/testsuite/gas/all/org-2.s
@@ -0,0 +1,9 @@
+	.data
+	.org	0x10
+	.globl	foo
+foo:
+	.byte	0, 1, 2, 3
+	.org	0x10
+	.globl	bar
+bar:
+	.byte	0, 1, 2, 3
diff --git a/gas/testsuite/gas/all/org-3.d b/gas/testsuite/gas/all/org-3.d
new file mode 100644
index 0000000..d719403
--- /dev/null
+++ b/gas/testsuite/gas/all/org-3.d
@@ -0,0 +1,2 @@
+#name: .org test 3
+#error-output: org-3.l
diff --git a/gas/testsuite/gas/all/org-3.l b/gas/testsuite/gas/all/org-3.l
new file mode 100644
index 0000000..2995bb0
--- /dev/null
+++ b/gas/testsuite/gas/all/org-3.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:6: Error: attempt to move \.org backwards
diff --git a/gas/testsuite/gas/all/org-3.s b/gas/testsuite/gas/all/org-3.s
new file mode 100644
index 0000000..3ec47ed
--- /dev/null
+++ b/gas/testsuite/gas/all/org-3.s
@@ -0,0 +1,9 @@
+	.data
+	.org	0x10
+	.globl	foo
+foo:
+	.byte	0, 1, 2, 3
+	.org	0x13
+	.globl	bar
+bar:
+	.byte	0, 1, 2, 3
diff --git a/gas/testsuite/gas/all/org-4.d b/gas/testsuite/gas/all/org-4.d
new file mode 100644
index 0000000..57b1e7f
--- /dev/null
+++ b/gas/testsuite/gas/all/org-4.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: .org test 4
+
+0+000014 . bar
+0+000010 . foo
diff --git a/gas/testsuite/gas/all/org-4.s b/gas/testsuite/gas/all/org-4.s
new file mode 100644
index 0000000..6f43492
--- /dev/null
+++ b/gas/testsuite/gas/all/org-4.s
@@ -0,0 +1,9 @@
+	.data
+	.org	0x10
+	.globl	foo
+foo:
+	.byte	0, 1, 2, 3
+	.org	0x14
+	.globl	bar
+bar:
+	.byte	0, 1, 2, 3
diff --git a/gas/testsuite/gas/all/org-5.d b/gas/testsuite/gas/all/org-5.d
new file mode 100644
index 0000000..45f72f3
--- /dev/null
+++ b/gas/testsuite/gas/all/org-5.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: .org test 5
+
+0+000015 . bar
+0+000010 . foo
diff --git a/gas/testsuite/gas/all/org-5.s b/gas/testsuite/gas/all/org-5.s
new file mode 100644
index 0000000..cf075aa
--- /dev/null
+++ b/gas/testsuite/gas/all/org-5.s
@@ -0,0 +1,9 @@
+	.data
+	.org	0x10
+	.globl	foo
+foo:
+	.byte	0, 1, 2, 3
+	.org	0x15
+	.globl	bar
+bar:
+	.byte	0, 1, 2, 3
diff --git a/gas/testsuite/gas/all/org-6.d b/gas/testsuite/gas/all/org-6.d
new file mode 100644
index 0000000..25fed71
--- /dev/null
+++ b/gas/testsuite/gas/all/org-6.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: .org test 6
+
+0+000018 . bar
+0+000010 . foo
diff --git a/gas/testsuite/gas/all/org-6.s b/gas/testsuite/gas/all/org-6.s
new file mode 100644
index 0000000..19ad016
--- /dev/null
+++ b/gas/testsuite/gas/all/org-6.s
@@ -0,0 +1,9 @@
+	.data
+	.org	0x10
+	.globl	foo
+foo:
+	.byte	0, 1, 2, 3
+	.org	0x18
+	.globl	bar
+bar:
+	.byte	0, 1, 2, 3
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 591af50..f0c6c34 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1806,6 +1806,19 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "debug-label-end-2"
     run_dump_test "debug-label-end-3"
 
+    run_dump_test "org-1"
+    run_dump_test "org-2"
+    run_dump_test "org-3"
+    run_dump_test "org-4"
+    run_dump_test "org-5"
+    run_dump_test "org-6"
+    run_dump_test "org-7"
+    run_dump_test "org-8"
+    run_dump_test "org-9"
+    run_dump_test "org-10"
+    run_dump_test "org-11"
+    run_dump_test "org-12"
+
     run_dump_test_arches "r6"		[mips_arch_list_matching mips32r6]
     if $has_newabi {
 	run_dump_test_arches "r6-n32"	[mips_arch_list_matching mips64r6]
diff --git a/gas/testsuite/gas/mips/org-1.d b/gas/testsuite/gas/mips/org-1.d
new file mode 100644
index 0000000..824d6ff
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-1.d
@@ -0,0 +1,7 @@
+#nm: -g --defined-only
+#as: --relax-branch
+#name: MIPS .org test 1
+#stderr: org-1.l
+
+0+100000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-1.l b/gas/testsuite/gas/mips/org-1.l
new file mode 100644
index 0000000..4dade81
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-1.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:4: Warning: relaxed out-of-range branch into a jump
diff --git a/gas/testsuite/gas/mips/org-1.s b/gas/testsuite/gas/mips/org-1.s
new file mode 100644
index 0000000..95177c3
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-1.s
@@ -0,0 +1,9 @@
+	.text
+	.globl	foo
+foo:
+	beqz	$2, lbar
+	.org	0x100000
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-10.d b/gas/testsuite/gas/mips/org-10.d
new file mode 100644
index 0000000..520e779
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-10.d
@@ -0,0 +1,7 @@
+#nm: -g --defined-only
+#as: --relax-branch
+#name: MIPS .org test 10
+#stderr: org-10.l
+
+0+100000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-10.l b/gas/testsuite/gas/mips/org-10.l
new file mode 100644
index 0000000..4dade81
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-10.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:4: Warning: relaxed out-of-range branch into a jump
diff --git a/gas/testsuite/gas/mips/org-10.s b/gas/testsuite/gas/mips/org-10.s
new file mode 100644
index 0000000..74a7d0c
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-10.s
@@ -0,0 +1,11 @@
+	.text
+	.globl	foo
+foo:
+	beqz	$2, lbar
+	.org	0x10
+	nop
+	.space	0xfffec
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-11.d b/gas/testsuite/gas/mips/org-11.d
new file mode 100644
index 0000000..b464230
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-11.d
@@ -0,0 +1,6 @@
+#nm: -g --defined-only
+#as: -32
+#name: MIPS .org test 11
+
+0+001000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-11.s b/gas/testsuite/gas/mips/org-11.s
new file mode 100644
index 0000000..61eefb2
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-11.s
@@ -0,0 +1,13 @@
+	.set	mips16
+	.text
+	.globl	foo
+foo:
+	la	$2, lbar
+	.org	0x4
+	nop
+	.space	0xffa
+	.align	2
+	.globl	bar
+bar = .
+lbar = .
+	nop
diff --git a/gas/testsuite/gas/mips/org-12.d b/gas/testsuite/gas/mips/org-12.d
new file mode 100644
index 0000000..323c301
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-12.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: MIPS .org test 12
+
+0+001000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-12.s b/gas/testsuite/gas/mips/org-12.s
new file mode 100644
index 0000000..5a01440
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-12.s
@@ -0,0 +1,13 @@
+	.set	micromips
+	.text
+	.globl	foo
+foo:
+	addu	$4, $3, $2
+	beqz	$2, lbar
+	.org	0x6
+	nop
+	.space	0xff8
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-2.d b/gas/testsuite/gas/mips/org-2.d
new file mode 100644
index 0000000..abdd563
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-2.d
@@ -0,0 +1,6 @@
+#nm: -g --defined-only
+#as: -32
+#name: MIPS .org test 2
+
+0+001000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-2.s b/gas/testsuite/gas/mips/org-2.s
new file mode 100644
index 0000000..6cb07bd
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-2.s
@@ -0,0 +1,11 @@
+	.set	mips16
+	.text
+	.globl	foo
+foo:
+	la	$2, lbar
+	.org	0x1000
+	.align	2
+	.globl	bar
+bar = .
+lbar = .
+	nop
diff --git a/gas/testsuite/gas/mips/org-3.d b/gas/testsuite/gas/mips/org-3.d
new file mode 100644
index 0000000..04d5208
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-3.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: MIPS .org test 3
+
+0+001000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-3.s b/gas/testsuite/gas/mips/org-3.s
new file mode 100644
index 0000000..d3c6eb4
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-3.s
@@ -0,0 +1,11 @@
+	.set	micromips
+	.text
+	.globl	foo
+foo:
+	addu	$4, $3, $2
+	beqz	$2, lbar
+	.org	0x1000
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-4.d b/gas/testsuite/gas/mips/org-4.d
new file mode 100644
index 0000000..9d6af7a
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-4.d
@@ -0,0 +1,3 @@
+#as: --relax-branch
+#name: MIPS .org test 4
+#error-output: org-4.l
diff --git a/gas/testsuite/gas/mips/org-4.l b/gas/testsuite/gas/mips/org-4.l
new file mode 100644
index 0000000..138515c
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-4.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:5: Error: attempt to move \.org backwards
+.*:4: Warning: relaxed out-of-range branch into a jump
diff --git a/gas/testsuite/gas/mips/org-4.s b/gas/testsuite/gas/mips/org-4.s
new file mode 100644
index 0000000..c81fde9
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-4.s
@@ -0,0 +1,11 @@
+	.text
+	.globl	foo
+foo:
+	beqz	$2, lbar
+	.org	0xc
+	nop
+	.space	0xffff0
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-5.d b/gas/testsuite/gas/mips/org-5.d
new file mode 100644
index 0000000..b8dca13
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-5.d
@@ -0,0 +1,3 @@
+#as: -32
+#name: MIPS .org test 5
+#error-output: org-5.l
diff --git a/gas/testsuite/gas/mips/org-5.l b/gas/testsuite/gas/mips/org-5.l
new file mode 100644
index 0000000..2995bb0
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-5.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:6: Error: attempt to move \.org backwards
diff --git a/gas/testsuite/gas/mips/org-5.s b/gas/testsuite/gas/mips/org-5.s
new file mode 100644
index 0000000..ae426b2
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-5.s
@@ -0,0 +1,13 @@
+	.set	mips16
+	.text
+	.globl	foo
+foo:
+	la	$2, lbar
+	.org	0x2
+	nop
+	.space	0xffc
+	.align	2
+	.globl	bar
+bar = .
+lbar = .
+	nop
diff --git a/gas/testsuite/gas/mips/org-6.d b/gas/testsuite/gas/mips/org-6.d
new file mode 100644
index 0000000..9bc6ce7
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-6.d
@@ -0,0 +1,2 @@
+#name: MIPS .org test 6
+#error-output: org-6.l
diff --git a/gas/testsuite/gas/mips/org-6.l b/gas/testsuite/gas/mips/org-6.l
new file mode 100644
index 0000000..d8ccddb
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-6.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*:7: Error: attempt to move \.org backwards
diff --git a/gas/testsuite/gas/mips/org-6.s b/gas/testsuite/gas/mips/org-6.s
new file mode 100644
index 0000000..bbc42b8
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-6.s
@@ -0,0 +1,13 @@
+	.set	micromips
+	.text
+	.globl	foo
+foo:
+	addu	$4, $3, $2
+	beqz	$2, lbar
+	.org	0x4
+	nop
+	.space	0xffa
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-7.d b/gas/testsuite/gas/mips/org-7.d
new file mode 100644
index 0000000..71f545d
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-7.d
@@ -0,0 +1,6 @@
+#nm: -g --defined-only
+#as: --relax-branch
+#name: MIPS .org test 7
+
+0+010000 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-7.s b/gas/testsuite/gas/mips/org-7.s
new file mode 100644
index 0000000..b0a88bd
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-7.s
@@ -0,0 +1,11 @@
+	.text
+	.globl	foo
+foo:
+	beqz	$2, lbar
+	.org	0x8
+	nop
+	.space	0xfff4
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/testsuite/gas/mips/org-8.d b/gas/testsuite/gas/mips/org-8.d
new file mode 100644
index 0000000..0d1acf9
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-8.d
@@ -0,0 +1,6 @@
+#nm: -g --defined-only
+#as: -32
+#name: MIPS .org test 8
+
+0+000100 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-8.s b/gas/testsuite/gas/mips/org-8.s
new file mode 100644
index 0000000..097163c
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-8.s
@@ -0,0 +1,13 @@
+	.set	mips16
+	.text
+	.globl	foo
+foo:
+	la	$2, lbar
+	.org	0x2
+	nop
+	.space	0xfc
+	.align	2
+	.globl	bar
+bar = .
+lbar = .
+	nop
diff --git a/gas/testsuite/gas/mips/org-9.d b/gas/testsuite/gas/mips/org-9.d
new file mode 100644
index 0000000..fe9e3f3
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-9.d
@@ -0,0 +1,5 @@
+#nm: -g --defined-only
+#name: MIPS .org test 9
+
+0+000080 . bar
+0+000000 . foo
diff --git a/gas/testsuite/gas/mips/org-9.s b/gas/testsuite/gas/mips/org-9.s
new file mode 100644
index 0000000..90405b3
--- /dev/null
+++ b/gas/testsuite/gas/mips/org-9.s
@@ -0,0 +1,13 @@
+	.set	micromips
+	.text
+	.globl	foo
+foo:
+	addu	$4, $3, $2
+	beqz	$2, lbar
+	.org	0x4
+	nop
+	.space	0x7a
+	.globl	bar
+bar:
+lbar:
+	nop
diff --git a/gas/write.c b/gas/write.c
index 9a99a0f..d570b6f 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -2692,7 +2692,11 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
 		  know (fragP->fr_next);
 		  after = fragP->fr_next->fr_address + stretch;
 		  growth = target - after;
-		  if (growth < 0)
+
+		  /* Growth may be negative, but variable part of frag
+		     cannot have fewer than 0 chars.  That is, we can't
+		     .org backwards.  */
+		  if (address + fragP->fr_fix > target)
 		    {
 		      growth = 0;
 
@@ -2714,9 +2718,6 @@ relax_segment (struct frag *segment_frag_root, segT segment, int pass)
 			  break;
 			}
 
-		      /* Growth may be negative, but variable part of frag
-			 cannot have fewer than 0 chars.  That is, we can't
-			 .org backwards.  */
 		      as_bad_where (fragP->fr_file, fragP->fr_line,
 				    _("attempt to move .org backwards"));


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]