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)
commit9875b36538d35f2292ddc3bb5e7c60e1582aa087
tree9de303f12626d4b6f99406f109f1f73e6072f04e
parent673cff9b8b3105f74ce97c202a0727f9e83e56e6
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.
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