• Bug#266660: Severe silent breakage in the mips assembler

    From Thiemo Seufer@1:229/2 to All on Wed Aug 18 19:20:13 2004
    From: [email protected]

    Package: binutils
    Version: 2.15-1
    Severity: grave
    Justification: generates silently broken executables
    Tags: patch

    Hello All,

    current binutils 2.15 have a long-standing bug in the mips assembler,
    which is increasingly likely to show up in more modern gcc versions
    (due to improved optimizations). The handling of delay slots in
    "branch-likely" branches is broken, and leads e.g. to this:

    [ralf@lappi tmp]$ cat s.s
    1: beqzl $2, 1b
    beq $4, $5, 1b
    [ralf@lappi tmp]$ mips-linux-as -mips2 -o s.o s.s
    [ralf@lappi tmp]$ mips-linux-objdump -d s.o

    s.o: file format elf32-tradbigmips

    Disassembly of section .text:

    00000000 <.text>:
    0: 1085ffff beq a0,a1,0x0
    4: 00000000 nop
    8: 50400000 beqzl v0,0xc
    c: 00000000 nop

    that is, the branches are swapped. The appended patch fixes it, it went
    already in upstream.


    Thiemo


    /gas/ChangeLog
    2004-08-18 Thiemo Seufer <[email protected]>
    * config/tc-mips.c (append_insn): Handle delay slots in branch likely
    correctly.

    /gas/testsuite/ChangeLog
    2004-08-18 Thiemo Seufer <[email protected]>
    * gas/mips/branch-swap.s: New testcase.
    * gas/mips/branch-swap.d: New testcase.
    * gas/mips/mips.exp: Run the testcase.


    --- gas/config/tc-mips.c.old 2004-05-17 21:36:10.000000000 +0200
    +++ gas/config/tc-mips.c 2004-08-17 20:00:43.000000000 +0200
    @@ -2708,6 +2708,7 @@ append_insn (struct mips_cl_insn *ip, ex
    prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
    prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
    prev_insn_extended = 0;
    + prev_insn_is_delay_slot = 1;
    }
    else
    {
    --- gas/testsuite/gas/mips/mips.exp.old 2004-08-17 22:50:38.000000000 +0200
    +++ gas/testsuite/gas/mips/mips.exp 2004-08-18 14:53:43.000000000 +0200
    @@ -429,6 +429,7 @@ if { [istarget mips*-*-*] } then {
    run_dump_test_arches "branch-misc-1" [mips_arch_list_matching mips1]
    run_list_test_arches "branch-misc-2" "-32 -non_shared" [mips_arch_list_matching mips1]
    run_list_test_arches "branch-misc-2pic" "-32 -call_shared" [mips_arch_list_matching mips1]
    + run_dump_test "branch-swap"

    if $ilocks {
    run_dump_test "div-ilocks"
    --- gas/testsuite/gas/mips/branch-swap.s.old 1970-01-01 01:00:00.000000000 +0100
    +++ gas/te