GAS: Fix bogus "attempt to move .org backwards" relaxation errors
authorMaciej W. Rozycki <macro@imgtec.com>
Thu, 2 Mar 2017 01:24:15 +0000 (01:24 +0000)
committerMaciej W. Rozycki <macro@imgtec.com>
Thu, 2 Mar 2017 01:44:07 +0000 (01:44 +0000)
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.

48 files changed:
gas/ChangeLog
gas/testsuite/gas/all/gas.exp
gas/testsuite/gas/all/org-1.d [new file with mode: 0644]
gas/testsuite/gas/all/org-1.l [new file with mode: 0644]
gas/testsuite/gas/all/org-1.s [new file with mode: 0644]
gas/testsuite/gas/all/org-2.d [new file with mode: 0644]
gas/testsuite/gas/all/org-2.l [new file with mode: 0644]
gas/testsuite/gas/all/org-2.s [new file with mode: 0644]
gas/testsuite/gas/all/org-3.d [new file with mode: 0644]
gas/testsuite/gas/all/org-3.l [new file with mode: 0644]
gas/testsuite/gas/all/org-3.s [new file with mode: 0644]
gas/testsuite/gas/all/org-4.d [new file with mode: 0644]
gas/testsuite/gas/all/org-4.s [new file with mode: 0644]
gas/testsuite/gas/all/org-5.d [new file with mode: 0644]
gas/testsuite/gas/all/org-5.s [new file with mode: 0644]
gas/testsuite/gas/all/org-6.d [new file with mode: 0644]
gas/testsuite/gas/all/org-6.s [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
gas/testsuite/gas/mips/org-1.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-1.l [new file with mode: 0644]
gas/testsuite/gas/mips/org-1.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-10.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-10.l [new file with mode: 0644]
gas/testsuite/gas/mips/org-10.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-11.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-11.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-12.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-12.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-2.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-3.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-4.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-4.l [new file with mode: 0644]
gas/testsuite/gas/mips/org-4.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-5.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-5.l [new file with mode: 0644]
gas/testsuite/gas/mips/org-5.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-6.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-6.l [new file with mode: 0644]
gas/testsuite/gas/mips/org-6.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-7.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-7.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-8.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-8.s [new file with mode: 0644]
gas/testsuite/gas/mips/org-9.d [new file with mode: 0644]
gas/testsuite/gas/mips/org-9.s [new file with mode: 0644]
gas/write.c

index 9be9530d054f8a1c89bc1ba2372fb8cba2d68c4c..785f9a4965f6427f78b7efbd5826e79faa1a2267 100644 (file)
@@ -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.
index 009e68c22015e222c41cd6494fc8d1bae44b24e5..b5b0bebbf35ada2a68868a7c00e1d7e0bdd55092 100644 (file)
@@ -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 (file)
index 0000000..983e6d6
--- /dev/null
@@ -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 (file)
index 0000000..79932c0
--- /dev/null
@@ -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 (file)
index 0000000..4d7b12b
--- /dev/null
@@ -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 (file)
index 0000000..6295a97
--- /dev/null
@@ -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 (file)
index 0000000..2995bb0
--- /dev/null
@@ -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 (file)
index 0000000..4eb0d1f
--- /dev/null
@@ -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 (file)
index 0000000..d719403
--- /dev/null
@@ -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 (file)
index 0000000..2995bb0
--- /dev/null
@@ -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 (file)
index 0000000..3ec47ed
--- /dev/null
@@ -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 (file)
index 0000000..57b1e7f
--- /dev/null
@@ -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 (file)
index 0000000..6f43492
--- /dev/null
@@ -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 (file)
index 0000000..45f72f3
--- /dev/null
@@ -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 (file)
index 0000000..cf075aa
--- /dev/null
@@ -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 (file)
index 0000000..25fed71
--- /dev/null
@@ -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 (file)
index 0000000..19ad016
--- /dev/null
@@ -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
index 591af507a27c3b9cd016828c75045c2c3d86f2a7..f0c6c34dcd2de9172aa3392ab5c0398aeded6ff6 100644 (file)
@@ -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 (file)
index 0000000..824d6ff
--- /dev/null
@@ -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 (file)
index 0000000..4dade81
--- /dev/null
@@ -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 (file)
index 0000000..95177c3
--- /dev/null
@@ -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 (file)
index 0000000..520e779
--- /dev/null
@@ -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 (file)
index 0000000..4dade81
--- /dev/null
@@ -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 (file)
index 0000000..74a7d0c
--- /dev/null
@@ -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 (file)
index 0000000..b464230
--- /dev/null
@@ -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 (file)
index 0000000..61eefb2
--- /dev/null
@@ -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 (file)
index 0000000..323c301
--- /dev/null
@@ -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 (file)
index 0000000..5a01440
--- /dev/null
@@ -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 (file)
index 0000000..abdd563
--- /dev/null
@@ -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 (file)
index 0000000..6cb07bd
--- /dev/null
@@ -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 (file)
index 0000000..04d5208
--- /dev/null
@@ -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 (file)
index 0000000..d3c6eb4
--- /dev/null
@@ -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 (file)
index 0000000..9d6af7a
--- /dev/null
@@ -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 (file)
index 0000000..138515c
--- /dev/null
@@ -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 (file)
index 0000000..c81fde9
--- /dev/null
@@ -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 (file)
index 0000000..b8dca13
--- /dev/null
@@ -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 (file)
index 0000000..2995bb0
--- /dev/null
@@ -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 (file)
index 0000000..ae426b2
--- /dev/null
@@ -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 (file)
index 0000000..9bc6ce7
--- /dev/null
@@ -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 (file)
index 0000000..d8ccddb
--- /dev/null
@@ -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 (file)
index 0000000..bbc42b8
--- /dev/null
@@ -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 (file)
index 0000000..71f545d
--- /dev/null
@@ -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 (file)
index 0000000..b0a88bd
--- /dev/null
@@ -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 (file)
index 0000000..0d1acf9
--- /dev/null
@@ -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 (file)
index 0000000..097163c
--- /dev/null
@@ -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 (file)
index 0000000..fe9e3f3
--- /dev/null
@@ -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 (file)
index 0000000..90405b3
--- /dev/null
@@ -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
index 9a99a0f5ae740a330fdaa6ca455759e31ae75907..d570b6f5baf8ff9e944cc8213fbed0f2270f447f 100644 (file)
@@ -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"));