The following has be reported by IBM LTC: Large external array causes SIGILL in 32-bit Please fill in each of the sections below. Hardware Environment: 4-way POWER4 Software Environment: SLES8 RC6 Steps to Reproduce: /home/xxue/work> cat bigdata.c int x[3000][3000][30]; int main() { return 10; } /home/xxue/work> gcc bigdata.c /home/xxue/work> a.out Illegal instruction (core dumped) /home/xxue/work> /opt/cross/bin/powerpc64-linux-gcc bigdata.c /home/xxue/work> a.out Actual Results: SIGILL Expected Results: clean pass Additional Information: The test cases passes in 64-bit mode. Here's the patch for RHEL3 (kernel 2.4.21-4.EL): --- linux-2.4.21-4.EL/fs/binfmt_elf.c 2003-11-11 17:45:13.000000000 +0530 +++ linux-2.4.21-4.EL.patched/fs/binfmt_elf.c 2003-11-11 17:46:49.000000000 +0530 @@ -80,13 +80,14 @@ #define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) -static void set_brk(unsigned long start, unsigned long end) +static unsigned set_brk(unsigned long start, unsigned long end) { + int retval=0; start = ELF_PAGEALIGN(start); end = ELF_PAGEALIGN(end); if (end <= start) return; - do_brk(start, end - start); + retval = do_brk(start, end - start); } @@ -367,7 +368,7 @@ unsigned long text_data, elf_entry = ~0UL; char * addr; loff_t offset; - + int retval; current->mm->end_code = interp_ex->a_text; text_data = interp_ex->a_text + interp_ex->a_data; current->mm->end_data = text_data; @@ -387,7 +388,9 @@ goto out; } - do_brk(0, text_data); + retval = do_brk(0, text_data); + if(BAD_ADDR(retval)) + goto out; if (!interpreter->f_op || !interpreter->f_op->read) goto out; if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0) @@ -395,8 +398,10 @@ flush_icache_range((unsigned long)addr, (unsigned long)addr + text_data); - do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), + retval = do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1), interp_ex->a_bss); + if(BAD_ADDR(retval)) + goto out; elf_entry = interp_ex->a_entry; out: @@ -720,7 +725,26 @@ end_code += load_bias; start_data += load_bias; end_data += load_bias; + + current->mm->end_code = end_code; + current->mm->start_code = start_code; + current->mm->start_data = start_data; + current->mm->end_data = end_data; + current->mm->start_stack = bprm->p; + + /* Calling set_brk effectively mmaps the pages that we need + * for the bss and break sections. + * We must do this now before we load the interpreter + * in case we have a huge bss region. + */ + retval = set_brk(elf_bss, elf_brk); + if(retval < 0) { + printk(KERN_ERR "unable to map bss section\n"); + send_sig(SIGSEGV, current, 0); + goto out_free_dentry; + } + padzero(elf_bss); if (elf_interpreter) { if (interpreter_type == INTERPRETER_AOUT) elf_entry = load_aout_interp(&interp_ex, @@ -764,20 +788,7 @@ /* N.B. passed_fileno might not be initialized? */ if (interpreter_type == INTERPRETER_AOUT) current->mm->arg_start += strlen(passed_fileno) + 1; - current->mm->start_brk = current->mm->brk = elf_brk; - current->mm->end_code = end_code; - current->mm->start_code = start_code; - current->mm->start_data = start_data; - current->mm->end_data = end_data; - current->mm->start_stack = bprm->p; - - /* Calling set_brk effectively mmaps the pages that we need - * for the bss and break sections - */ - set_brk(elf_bss, elf_brk); - - padzero(elf_bss); - + #if 0 printk("(start_brk) %lx\n" , (long) current->mm->start_brk); printk("(end_code) %lx\n" , (long) current->mm->end_code);
Closed, IBM will retest in RHEL 3 environment.