Bug#254626: gcc-3.3: wrong optimization on sparc32 when building linux kernel
Package: gcc-3.3
Version: 1:3.3.4-1
Severity: normal
Am building linux kernel 2.6.6 with CONFIG_CC_OPTIMIZE_FOR_SIZE=y set in .config.
This results in -Os parameter to gcc.
Resulting kernel does not boot and causes an oops (see below). This comes from
this code in lib/vsprintf.c function vsnprintf:
...
if (qualifier == 'L')
num = va_arg(args, long long);
else if (qualifier == 'l') {
num = va_arg(args, unsigned long);
if (flags & SIGN)
num = (signed long) num;
} else if (qualifier == 'Z' || qualifier == 'z') {
...
which gets compiled into:
f00bb118: 80 a1 60 4c cmp %g5, 0x4c
f00bb11c: 12 80 00 09 bne f00bb140 <vsnprintf+0x4fc>
f00bb120: 80 a1 60 6c cmp %g5, 0x6c
f00bb124: 94 10 20 08 mov 8, %o2
f00bb128: 92 10 00 1b mov %i3, %o1
f00bb12c: 40 00 0e eb call f00becd8 <__memcpy>
f00bb130: 90 07 bf f0 add %fp, -16, %o0
f00bb134: d4 1a 00 00 ldd [ %o0 ], %o2
f00bb138: 10 80 00 2b b f00bb1e4 <vsnprintf+0x5a0>
f00bb13c: b6 06 e0 08 add %i3, 8, %i3
The 8 in f00bb124 is correct for 'long long', but 'unsigned long' is 4 bytes on this
platform. This code gets executed when the "%llu" format string is used as a printk()
argument. The build line looks like:
gcc -Wp,-MD,lib/.vsprintf.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude
-Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common
-m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7 -Os -fomit-frame-pointer
-DKBUILD_BASENAME=vsprintf -DKBUILD_MODNAME=vsprintf -c -o lib/vsprintf.o
lib/vsprintf.c
Recompiling this file with -O0 resolves the oops. The code then looks like:
f00bf9dc: 80 a0 60 4c cmp %g1, 0x4c
f00bf9e0: 12 80 00 19 bne f00bfa44 <vsnprintf+0xa10>
f00bf9e4: 01 00 00 00 nop
f00bf9e8: c4 07 a0 50 ld [ %fp + 0x50 ], %g2
f00bf9ec: 82 00 a0 08 add %g2, 8, %g1
f00bf9f0: c2 27 a0 50 st %g1, [ %fp + 0x50 ]
f00bf9f4: c2 08 80 00 ldub [ %g2 ], %g1
f00bf9f8: c2 2f bf b0 stb %g1, [ %fp + -80 ]
f00bf9fc: c2 08 a0 01 ldub [ %g2 + 1 ], %g1
f00bfa00: c2 2f bf b1 stb %g1, [ %fp + -79 ]
f00bfa04: c2 08 a0 02 ldub [ %g2 + 2 ], %g1
f00bfa08: c2 2f bf b2 stb %g1, [ %fp + -78 ]
f00bfa0c: c2 08 a0 03 ldub [ %g2 + 3 ], %g1
f00bfa10: c2 2f bf b3 stb %g1, [ %fp + -77 ]
f00bfa14: c2 08 a0 04 ldub [ %g2 + 4 ], %g1
f00bfa18: c2 2f bf b4 stb %g1, [ %fp + -76 ]
f00bfa1c: c2 08 a0 05 ldub [ %g2 + 5 ], %g1
f00bfa20: c2 2f bf b5 stb %g1, [ %fp + -75 ]
f00bfa24: c2 08 a0 06 ldub [ %g2 + 6 ], %g1
f00bfa28: c2 2f bf b6 stb %g1, [ %fp + -74 ]
f00bfa2c: c2 08 a0 07 ldub [ %g2 + 7 ], %g1
f00bfa30: c2 2f bf b7 stb %g1, [ %fp + -73 ]
f00bfa34: c4 1f bf b0 ldd [ %fp + -80 ], %g2
f00bfa38: c4 3f bf e8 std %g2, [ %fp + -24 ]
f00bfa3c: 10 80 00 57 b f00bfb98 <vsnprintf+0xb64>
f00bfa40: 01 00 00 00 nop
f00bfa44: c2 07 bf c0 ld [ %fp + -64 ], %g1
f00bfa48: 80 a0 60 6c cmp %g1, 0x6c
f00bfa4c: 12 80 00 14 bne f00bfa9c <vsnprintf+0xa68>
f00bfa50: 01 00 00 00 nop
f00bfa54: c4 07 a0 50 ld [ %fp + 0x50 ], %g2
f00bfa58: 82 00 a0 04 add %g2, 4, %g1
f00bfa5c: c2 27 a0 50 st %g1, [ %fp + 0x50 ]
f00bfa60: c2 00 80 00 ld [ %g2 ], %g1
f00bfa64: 84 10 20 00 clr %g2
f00bfa68: 86 10 00 01 mov %g1, %g3
f00bfa6c: c4 3f bf e8 std %g2, [ %fp + -24 ]
f00bfa70: c2 07 bf cc ld [ %fp + -52 ], %g1
f00bfa74: 82 08 60 02 and %g1, 2, %g1
f00bfa78: 80 a0 60 00 cmp %g1, 0
Have not tried other optimization levels or compiler options.
-- Kernel oops during boot:
scsi0 : Sparc ESP100A-FAST
Using deadline io scheduler
Vendor: SEAGATE Model: ST39173W SUN9.0G Rev: 7063
Type: Direct-Access ANSI SCSI revision: 02
Vendor: SEAGATE Model: ST32550W SUN2.1G Rev: 0416
Type: Direct-Access ANSI SCSI revision: 02
scsi1 : Sparc ESP236-FAST
esp0: target 1 [period 100ns offset 15 10.00MHz FAST SCSI-II]
Unable to handle kernel NULL pointer dereference
tsk->{mm,active_mm}->context = ffffffff
tsk->{mm,active_mm}->pgd = fc000000
\|/ ____ \|/
"@'/ ,. \`@"
/_| \__/ |_\
\__U_/
swapper(1): Oops [#1]
PSR: 40401fc0 PC: f00bb134 NPC: f00bb138 Y: 00000000 Not tainted
PC: <vsnprintf+0x4f0/0x604>
%G: 00000001 00000008 00000000 010deab3 f015901c 0000004c f01ea000 00000001
%O: 00000000 f01ebc24 00000008 0000045a fffffecc 00000000 f01eba80 f00bb12c
RPC: <vsnprintf+0x4e8/0x604>
%L: ffffffff 00000000 f01b57ff ffffffff f01b5400 00000000 0098963b 821a0580
%I: f01b5414 00000400 0000000a f01ebc1c 00000018 f01edc2c f01ebaf8 f00bb25c
Caller[f00bb25c]: vscnprintf+0x14/0x30
Caller[f0031bdc]: printk+0x60/0x188
Caller[f00edac0]: sd_read_capacity+0x364/0x3d4
Caller[f00ee060]: sd_revalidate_disk+0xcc/0x12c
Caller[f00ee34c]: sd_probe+0x28c/0x350
Caller[f00d2534]: bus_match+0x40/0x6c
Caller[f00d2638]: driver_attach+0x3c/0x90
Caller[f00d2874]: bus_add_driver+0x64/0x7c
Caller[f00d2b60]: driver_register+0x24/0x34
Caller[f0194eec]: do_initcalls+0x60/0xd8
Caller[f00100b4]: init+0x1c/0x10c
Caller[f0018100]: kernel_thread+0x34/0x50
Caller[f0010024]: rest_init+0x10/0x24
Caller[f0194e64]: start_kernel+0x208/0x21c
Caller[f0194790]: sun4c_continue_boot+0x314/0x324
Caller[00000000]: 0x0
Instruction DUMP: 9210001b 40000eeb 9007bff0 <d41a0000> 1080002b b606e008 12
Kernel panic: Attempted to kill init!
<0>Press L1-A to return to the boot prom
-- System Information:
Debian Release: testing/unstable
APT prefers testing
APT policy: (990, 'testing'), (500, 'unstable')
Architecture: sparc
Kernel: Linux 2.4.26-sparc32
Locale: LANG=en_GB.ISO-8859-15, LC_CTYPE=en_GB.ISO-8859-15
Versions of packages gcc-3.3 depends on:
ii binutils 2.14.90.0.7-8 The GNU assembler, linker and bina
ii cpp-3.3 1:3.3.4-1 The GNU C preprocessor
ii gcc-3.3-base 1:3.3.4-1 The GNU Compiler Collection (base
ii libc6 2.3.2.ds1-12 GNU C Library: Shared libraries an
ii libgcc1 1:3.3.4-1 GCC support library
-- no debconf information
Reply to: