Skip to contentSkip to conversation

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.

DISCUSSION C Hanish Menon 1 participant 1 message Mar 17, 2002 MIPS

lore
Share & tools
lore
#0 lore raw

Hi

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 oss.sgi.com 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:

-----------------------------------------------------------------------------
binutils-mipsel-linux-2.9.5-3
egcs-mipsel-linux-1.1.2-4

******************************* 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;

	/* TEMPORARY TO SHOW THE CROSS GCC bUg */
	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();

	/* TEMPORARY TO SHOW THE CROSS GCC bUg */
	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;

	/* TEMPORARY TO SHOW THE CROSS GCC bUg */
	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 :-)
HanishKVC

_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com