[Top] [All Lists]

Bug in (binutils-mipsel-linux-2.9.5-3 + egcs-mipsel-linux-1.1.2-4) - Al

To: linux-mips kernel <>,
Subject: Bug in (binutils-mipsel-linux-2.9.5-3 + egcs-mipsel-linux-1.1.2-4) - Also any suggestion for binutils/gcc versions to use for mips.
From: C Hanish Menon <>
Date: Mon, 18 Mar 2002 00:05:56 +0530
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.8) Gecko/20020214

Sometime back I had ported Linux to LSI's SC2005 (TinyMips core with Mips1
and some Mips2 instructions) based board as part of my work.
We wanted to release the code to opensource. However we found
a bug in the code that it was corrupting the softirq's pending, which I
wanted to fix before releaseing to opensource. At that time I
temporarily fixed the problem by checking that the softirq is pointing
to a proper logic rather than 0 before calling it.

Recently I found time to look into the problem, and found the code
generated by the compiler is wrong, in that instead of setting the
ksoftirqd_task element of the irq_stat structure its setting the pending
element, thus causing the system to crash.

As mentioned in the subject I was using

binutils-mipsel-linux-2.95.3 and egcs-mipsel-linux-1.1.2-4 binary packages
from on a Redhat 7.2 system.

To show the problem I added some test code into the kernel/softirq.c
file, as can be noted from the code below the compiler generates proper
code in certain places, but wrong code at other instances:


******************************* ISSUE 1 ****************************

Location of irq_stat[]

00000000800f5d38 g     F .text  00000000000000d8 __tcp_mem_reclaim
00000000801614d0 g     O .data  0000000000000020 irq_stat
00000000800820dc g     F .text  0000000000000034 show_buffers

In ksoftirqd function /** The actual code - wrong code generated **/

        ksoftirqd_task(cpu) = current;
        /* added by me */
        debugkvc_softirq_pending("ksoftirqd: before for");

        for (;;) {
                if (!softirq_pending(cpu))

0000000080059b38 <ksoftirqd>:
     80059bf0:  3c108016        lui     $s0,0x8016
     80059bf4:  261014d0        addiu   $s0,$s0,5328
     80059bf8:  0c01667e        jal     800599f8 <debugkvc_softirq_pending>
     80059bfc:  ae1c0000        sw      $gp,0($s0) /** NOTE ksoftirqd_task 
offset is wrong **/
     80059c00:  2610fff0        addiu   $s0,$s0,-16 /** Nice way to calculate 
the pending element
offset but its wrong has the ksoftirqd_task element offset itself is wrong **/
     80059c04:  8e020000        lw      $v0,0($s0) /** as mentioned above the 
pending element offset wrong **/
     80059c08:  00000000        nop
     80059c0c:  14400003        bnez    $v0,80059c1c <ksoftirqd+0xe4>


void debugkvc_show_gcc_bug_1(void) /* Test case 1 - Proper code generated */
        int cpu = smp_processor_id();
        int pending;

        pending = softirq_pending(cpu);
        pending += 1;
        softirq_pending(cpu) = pending;
        ksoftirqd_task(cpu) = current;
        /* END */

0000000080059994 <debugkvc_show_gcc_bug_1>:
     80059994:  3c038016        lui     $v1,0x8016
     80059998:  246314d0        addiu   $v1,$v1,5328
     8005999c:  8c620000        lw      $v0,0($v1)
     800599a0:  ac7c0010        sw      $gp,16($v1) /** Proper offset for 
ksoftirqd_task element **/
     800599a4:  24420001        addiu   $v0,$v0,1
     800599a8:  03e00008        jr      $ra
     800599ac:  ac620000        sw      $v0,0($v1)


void debugkvc_show_gcc_bug_3(void) /* Test case 2 - WRONG code generated */
        int cpu = smp_processor_id();

        ksoftirqd_task(cpu) = current;
        /* END */

00000000800599cc <debugkvc_show_gcc_bug_3>:
     800599cc:  3c018016        lui     $at,0x8016
     800599d0:  ac3c14d0        sw      $gp,5328($at) /** wrong offset **/
     800599d4:  03e00008        jr      $ra
     800599d8:  00000000        nop


void debugkvc_show_gcc_bug_4(void) /* Test case 3 - WRONG code generated */
        int cpu = smp_processor_id();
        volatile void * task;

        task = ksoftirqd_task(cpu);
        ksoftirqd_task(cpu) = current;
        ksoftirqd_task(cpu) = task+1;
        /* END */

00000000800599dc <debugkvc_show_gcc_bug_4>:
     800599dc:  3c038016        lui     $v1,0x8016
     800599e0:  246314d0        addiu   $v1,$v1,5328
     800599e4:  8c620000        lw      $v0,0($v1) /** wrong offset **/
     800599e8:  00000000        nop
     800599ec:  24420001        addiu   $v0,$v0,1
     800599f0:  03e00008        jr      $ra
     800599f4:  ac620000        sw      $v0,0($v1)

00000000800599f8 <debugkvc_softirq_pending>:

******************************* ISSUE 2 ****************************

mipsel-linux-ld doesn't seem to understand elf32-littlemips even thou
mipsel-linux-objdump -i gives elf32-littlemips has part of its output

This issue affects the logic used in arch/mips/ramdisk/Makefile to
convert the
ramdisk.gz file to ramdisk.o

Had to force elf32-little for the logic to work.


*************** Current status *****************

Because of this, I download the sources for binutils 2.12 and gcc 3.0.4 and
created cross compilers for mipsel-linux. Now the compiler is generating
proper code for the above case. But linux is failing in the gzips
inflate logic (Compressed ramdisk) in some cases, have to verify it
properly and identify the issue. It again seems like a compiler problem,
but haven't verified it yet.

Also I have currently used 2.4.16 with code from linux-mips-kernel on
sourceforge as the base on which I have done my porting. Once I find the
issue with the gzip logic and also move it to 2.4.18 (or 2.4.19 if it
gets released by then), we will release the port to the opensource.

**************** Any suggestions ****************

In the mean time what do you people think is the best binutils/gcc
combination for working with latest Linux kernels for Mips.

Keep :-)

Do You Yahoo!?
Get your free address at

<Prev in Thread] Current Thread [Next in Thread>
  • Bug in (binutils-mipsel-linux-2.9.5-3 + egcs-mipsel-linux-1.1.2-4) - Also any suggestion for binutils/gcc versions to use for mips., C Hanish Menon <=