GAS: Fix bogus "attempt to move .org backwards" relaxation errors

Fix a commit 6afe8e98a6 ("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.
This commit is contained in:
Maciej W. Rozycki 2017-03-02 01:24:15 +00:00
parent 673cff9b8b
commit 9875b36538
48 changed files with 411 additions and 4 deletions

View 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.

View 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"

View File

@ -0,0 +1,3 @@
#name: .org test 1
#as: -gdwarf2
#error-output: org-1.l

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:22: Error: attempt to move \.org backwards

View File

@ -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

View File

@ -0,0 +1,2 @@
#name: .org test 2
#error-output: org-2.l

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:6: Error: attempt to move \.org backwards

View File

@ -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

View File

@ -0,0 +1,2 @@
#name: .org test 3
#error-output: org-3.l

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:6: Error: attempt to move \.org backwards

View File

@ -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

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: .org test 4
0+000014 . bar
0+000010 . foo

View File

@ -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

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: .org test 5
0+000015 . bar
0+000010 . foo

View File

@ -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

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: .org test 6
0+000018 . bar
0+000010 . foo

View File

@ -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

View 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]

View File

@ -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

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:4: Warning: relaxed out-of-range branch into a jump

View File

@ -0,0 +1,9 @@
.text
.globl foo
foo:
beqz $2, lbar
.org 0x100000
.globl bar
bar:
lbar:
nop

View File

@ -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

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:4: Warning: relaxed out-of-range branch into a jump

View File

@ -0,0 +1,11 @@
.text
.globl foo
foo:
beqz $2, lbar
.org 0x10
nop
.space 0xfffec
.globl bar
bar:
lbar:
nop

View File

@ -0,0 +1,6 @@
#nm: -g --defined-only
#as: -32
#name: MIPS .org test 11
0+001000 . bar
0+000000 . foo

View File

@ -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

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: MIPS .org test 12
0+001000 . bar
0+000000 . foo

View File

@ -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

View File

@ -0,0 +1,6 @@
#nm: -g --defined-only
#as: -32
#name: MIPS .org test 2
0+001000 . bar
0+000000 . foo

View File

@ -0,0 +1,11 @@
.set mips16
.text
.globl foo
foo:
la $2, lbar
.org 0x1000
.align 2
.globl bar
bar = .
lbar = .
nop

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: MIPS .org test 3
0+001000 . bar
0+000000 . foo

View File

@ -0,0 +1,11 @@
.set micromips
.text
.globl foo
foo:
addu $4, $3, $2
beqz $2, lbar
.org 0x1000
.globl bar
bar:
lbar:
nop

View File

@ -0,0 +1,3 @@
#as: --relax-branch
#name: MIPS .org test 4
#error-output: org-4.l

View File

@ -0,0 +1,3 @@
.*: Assembler messages:
.*:5: Error: attempt to move \.org backwards
.*:4: Warning: relaxed out-of-range branch into a jump

View File

@ -0,0 +1,11 @@
.text
.globl foo
foo:
beqz $2, lbar
.org 0xc
nop
.space 0xffff0
.globl bar
bar:
lbar:
nop

View File

@ -0,0 +1,3 @@
#as: -32
#name: MIPS .org test 5
#error-output: org-5.l

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:6: Error: attempt to move \.org backwards

View File

@ -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

View File

@ -0,0 +1,2 @@
#name: MIPS .org test 6
#error-output: org-6.l

View File

@ -0,0 +1,2 @@
.*: Assembler messages:
.*:7: Error: attempt to move \.org backwards

View File

@ -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

View File

@ -0,0 +1,6 @@
#nm: -g --defined-only
#as: --relax-branch
#name: MIPS .org test 7
0+010000 . bar
0+000000 . foo

View File

@ -0,0 +1,11 @@
.text
.globl foo
foo:
beqz $2, lbar
.org 0x8
nop
.space 0xfff4
.globl bar
bar:
lbar:
nop

View File

@ -0,0 +1,6 @@
#nm: -g --defined-only
#as: -32
#name: MIPS .org test 8
0+000100 . bar
0+000000 . foo

View File

@ -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

View File

@ -0,0 +1,5 @@
#nm: -g --defined-only
#name: MIPS .org test 9
0+000080 . bar
0+000000 . foo

View File

@ -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

View 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"));