function with stack arrays corrupts saved registers on stack
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Fix Released
|
Undecided
|
Zhenqiang Chen | ||
Linaro Toolchain Binaries |
Fix Released
|
Undecided
|
Unassigned | ||
linaro-networking |
Fix Released
|
Medium
|
Unassigned | ||
gcc-4.8 (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
Problem high level description
-------
Crash in xhci_mem_init function was observed on Arndale eval
board, when code was compiled by 4.8-2013.09 Linaro compiler.
Upon investigation it was found that compiler generates code
in xhci_check_
value saved on stack, when code returns and restore bad value
of $r8 xhci_mem_init crashes. xhci_check_
has complicated arrays create on the stack, most likely size
of those arrays was miscalculated.
Reproduce the issue
-------------------
Here is two ways to reproduce the issue. All test cases are in attached tarball.
1) Full post processed xhci-mem.c is attached as full/xhci-mem.i. Compile line
used by kernel build is attached as full/xhci-mem.sh
2) Smaller test case after running xhci-mem.i through delta script attached
as minimal/test.c and script compile script minimal/test.sh
Disassemble of xhci_check_
-------
Here is annotated disassemble of problematic function. It
shows that code corrups location where r8 registers is
stored. Real value cited are from below debug session
log.
(gdb) disassemble xhci_check_
Dump of assembler code for function xhci_check_
0x803194e4 <+0>: stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} <-------- sp = sp0 - 36 = 0xEF17BC44 (9 registers)
0x803194e8 <+4>: sub sp, #444 ; 0x1bc <---- sp = sp - 444 = sp0 - 36 - 444 = sp0 - 480 = 0xEF17BA88
0x803194ea <+6>: push {lr} <---- sp = sp - 4 = sp0 - 480 - 4 = sp0 - 484 = 0xEF17BA84
0x803194ec <+8>: bl 0x8000cc8c <__gnu_mcount_nc> <---- in __gnu_mcount_nc sp = sp + 4 = sp0 - 480 = 0xEF17BA88
0x803194f0 <+12>: mov r9, r0
0x803194f2 <+14>: movs r5, #0
0x803194f4 <+16>: ldr r0, [r0, #116] ; 0x74
0x803194f6 <+18>: mov r11, r5
0x803194f8 <+20>: ldr.w r1, [r9, #96] ; 0x60
0x803194fc <+24>: add.w lr, sp, #184 ; 0xb8
0x80319500 <+28>: str r5, [sp, #32]
0x80319502 <+30>: add r7, sp, #440 ; 0x1b8 <---- r7 = sp + 440 = sp0 - 480 + 440 = sp0 - 40 = 0xef17bc40
0x80319504 <+32>: ldr.w r8, [r0]
0x80319508 <+36>: ldr r0, [r1, #0]
0x8031950a <+38>: str r5, [sp, #36] ; 0x24
0x8031950c <+40>: str r5, [sp, #52] ; 0x34
0x8031950e <+42>: ldrd r4, r5, [r8, #8]
0x80319512 <+46>: ldr r2, [r0, #0]
0x80319514 <+48>: ldr.w r10, [r8]
0x80319518 <+52>: adds.w r3, r5, #64 ; 0x40
0x8031951c <+56>: str.w r8, [lr]
0x80319520 <+60>: str.w r2, [lr, #68] ; 0x44
0x80319524 <+64>: adc.w r2, r4, #0
0x80319528 <+68>: strd r2, r3, [lr, #112] ; 0x70
0x8031952c <+72>: subs.w r3, r5, #16
0x80319530 <+76>: adc.w r2, r4, #4294967295
0x80319534 <+80>: add.w r6, r10, #1008 ; 0x3f0
0x80319538 <+84>: strd r2, r3, [r7, #16] <----- r7 + 16 = sp0 - 40 + 16 = sp0 - 24 = 0xef17bc50
0x8031953c <+88>: ldrd r2, r3, [sp, #32]
0x80319540 <+92>: str r6, [sp, #48] ; 0x30
Full DS-5 debug log
-------------------
Complete debugging session details
Execution stopped at breakpoint 2: N:0x803194E4
On core Cortex-A15_0 (ID 0)
N:0x803194E4 PUSH {r4-r11,lr}
x /40i 0x803194E4
N:0x803194E4 : PUSH {r4-r11,lr}
N:0x803194E8 : SUB sp,sp,#0x1bc
N:0x803194EA : PUSH {lr}
N:0x803194EC : BL {pc}-0x30c860 ; 0x8000cc8c
N:0x803194F0 : MOV r9,r0
N:0x803194F2 : MOVS r5,#0
N:0x803194F4 : LDR r0,[r0,#0x74]
N:0x803194F6 : MOV r11,r5
N:0x803194F8 : LDR r1,[r9,#0x60]
N:0x803194FC : ADD lr,sp,#0xb8
N:0x80319500 : STR r5,[sp,#0x20]
N:0x80319502 : ADD r7,sp,#0x1b8
N:0x80319504 : LDR r8,[r0,#0]
N:0x80319508 : LDR r0,[r1,#0]
N:0x8031950A : STR r5,[sp,#0x24]
N:0x8031950C : STR r5,[sp,#0x34]
N:0x8031950E : LDRD r4,r5,[r8,#8]
N:0x80319512 : LDR r2,[r0,#0]
N:0x80319514 : LDR r10,[r8,#0]
N:0x80319518 : ADDS r3,r5,#0x40
N:0x8031951C : STR r8,[lr,#0]
N:0x80319520 : STR r2,[lr,#0x44]
N:0x80319524 : ADC r2,r4,#0
N:0x80319528 : STRD r2,r3,[lr,#0x70]
N:0x8031952C : SUBS r3,r5,#0x10
N:0x80319530 : ADC r2,r4,#0xffffffff
N:0x80319534 : ADD r6,r10,#0x3f0
N:0x80319538 : STRD r2,r3,[r7,#0x10] <-------
N:0x8031953C : LDRD r2,r3,[sp,#0x20]
N:0x80319540 : STR r6,[sp,#0x30]
N:0x80319542 : STR r6,[lr,#8]
N:0x80319546 : MOV r6,r11
N:0x80319548 : STRD r2,r3,[r7,#-0x180]!
<snip>
p /x $sp
$4 = 0xEF17BC68
si
Execution stopped at: N:0x803194E8
On core Cortex-A15_0 (ID 0)
N:0x803194E8 SUB sp,sp,#0x1bc
p /x $sp
$5 = 0xEF17BC44
info reg
R0 0xEEB30000 0xEEB30000
R1 0xF014E400 0xF014E400
R2 0x00000000 0x00000000
R3 0xEEB1E6C0 0xEEB1E6C0
R4 0xF0160460 0xF0160460
R5 0xAEB36001 0xAEB36001
R6 0xEF268E10 0xEF268E10
R7 0xF0160020 0xF0160020
R8 0xEEB30000 0xEEB30000
R9 0x00000080 0x00000080
R10 0x00000000 0x00000000
R11 0x806924D4 0x806924D4
R12 0x80319335 0x80319335
SP 0xEF17BC44 0xEF17BC44
LR 0x8031AE61 0x8031AE61
PC 0x803194E8 0x803194E8
CPSR 0xA0000333 NzCvq_ge3ge2ge1
x /10w $sp
N:0xEF17BC44: 0xF0160460 0xAEB36001 0xEF268E10 0xF0160020
N:0xEF17BC54: 0xEEB30000 0x00000080 0x00000000 0x806924D4
N:0xEF17BC64: 0x8031AE61 0x00000000
si
Execution stopped at: N:0x803194EA
On core Cortex-A15_0 (ID 0)
N:0x803194EA PUSH {lr}
p /x $sp
$6 = 0xEF17BA88
si
Execution stopped at: N:0x803194EC
On core Cortex-A15_0 (ID 0)
N:0x803194EC BL {pc}-0x30c860 ; 0x8000cc8c
p /x $sp
$7 = 0xEF17BA84
si
Execution stopped at: N:0x8000CC8C
On core Cortex-A15_0 (ID 0)
N:0x8000CC8C MOV r12,lr
si
Execution stopped at: N:0x8000CC8E
On core Cortex-A15_0 (ID 0)
N:0x8000CC8E POP {lr}
p /x $sp
$8 = 0xEF17BA84
si
Execution stopped at: N:0x8000CC92
On core Cortex-A15_0 (ID 0)
N:0x8000CC92 MOV pc,r12
p /x $sp
$9 = 0xEF17BA88
si
Execution stopped at breakpoint 3: N:0x803194F0
On core Cortex-A15_0 (ID 0)
N:0x803194F0 MOV r9,r0
p /x $sp
$10 = 0xEF17BA88
si
Execution stopped at: N:0x803194F2
On core Cortex-A15_0 (ID 0)
N:0x803194F2 MOVS r5,#0
si
Execution stopped at: N:0x803194F2
On core Cortex-A15_0 (ID 0)
N:0x803194F2 MOVS r5,#0
dis 3
Breakpoint 3 disabled
si
Execution stopped at: N:0x803194F4
On core Cortex-A15_0 (ID 0)
N:0x803194F4 LDR r0,[r0,#0x74]
si
Execution stopped at: N:0x803194F6
On core Cortex-A15_0 (ID 0)
N:0x803194F6 MOV r11,r5
si
Execution stopped at: N:0x803194F8
On core Cortex-A15_0 (ID 0)
N:0x803194F8 LDR r1,[r9,#0x60]
si
Execution stopped at: N:0x803194FC
On core Cortex-A15_0 (ID 0)
N:0x803194FC ADD lr,sp,#0xb8
si
Execution stopped at: N:0x80319500
On core Cortex-A15_0 (ID 0)
N:0x80319500 STR r5,[sp,#0x20]
p /x $sp
$11 = 0xEF17BA88
si
Execution stopped at: N:0x80319502
On core Cortex-A15_0 (ID 0)
N:0x80319502 ADD r7,sp,#0x1b8
si
Execution stopped at: N:0x80319504
On core Cortex-A15_0 (ID 0)
N:0x80319504 LDR r8,[r0,#0]
p /x $r7
$12 = 0xEF17BC40
p /x $sp
$13 = 0xEF17BA88
si
Execution stopped at: N:0x80319508
On core Cortex-A15_0 (ID 0)
N:0x80319508 LDR r0,[r1,#0]
si
Execution stopped at: N:0x8031950A
On core Cortex-A15_0 (ID 0)
N:0x8031950A STR r5,[sp,#0x24]
si
Execution stopped at: N:0x8031950C
On core Cortex-A15_0 (ID 0)
N:0x8031950C STR r5,[sp,#0x34]
si
Execution stopped at: N:0x8031950E
On core Cortex-A15_0 (ID 0)
N:0x8031950E LDRD r4,r5,[r8,#8]
si
Execution stopped at: N:0x80319512
On core Cortex-A15_0 (ID 0)
N:0x80319512 LDR r2,[r0,#0]
si
Execution stopped at: N:0x80319514
On core Cortex-A15_0 (ID 0)
N:0x80319514 LDR r10,[r8,#0]
si
Execution stopped at: N:0x80319518
On core Cortex-A15_0 (ID 0)
N:0x80319518 ADDS r3,r5,#0x40
si
Execution stopped at: N:0x8031951C
On core Cortex-A15_0 (ID 0)
N:0x8031951C STR r8,[lr,#0]
si
Execution stopped at: N:0x80319520
On core Cortex-A15_0 (ID 0)
N:0x80319520 STR r2,[lr,#0x44]
si
Execution stopped at: N:0x80319524
On core Cortex-A15_0 (ID 0)
N:0x80319524 ADC r2,r4,#0
si
Execution stopped at: N:0x80319528
On core Cortex-A15_0 (ID 0)
N:0x80319528 STRD r2,r3,[lr,#0x70]
si
Execution stopped at: N:0x8031952C
On core Cortex-A15_0 (ID 0)
N:0x8031952C SUBS r3,r5,#0x10
si
Execution stopped at: N:0x80319530
On core Cortex-A15_0 (ID 0)
N:0x80319530 ADC r2,r4,#0xffffffff
si
Execution stopped at: N:0x80319534
On core Cortex-A15_0 (ID 0)
N:0x80319534 ADD r6,r10,#0x3f0
si
Execution stopped at: N:0x80319538
On core Cortex-A15_0 (ID 0)
N:0x80319538 STRD r2,r3,[r7,#0x10]
x /1wx 0xEF17BC54
N:0xEF17BC54: 0xEEB30000
p /x $r3
$14 = 0xAEB363F0
si
Execution stopped at: N:0x8031953C
On core Cortex-A15_0 (ID 0)
N:0x8031953C LDRD r2,r3,[sp,#0x20]
x /1wx 0xEF17BC54
N:0xEF17BC54: 0xAEB363F0
Changed in gcc-linaro: | |
assignee: | nobody → Zhenqiang Chen (zhenqiang-chen) |
Changed in linaro-networking: | |
importance: | Undecided → Medium |
Changed in linaro-networking: | |
status: | New → Fix Released |
4.7 vs 4.8
----------
Checked the same code under 4.7. linaro 4.7-2013. 04-20130415 does not have
this problem. Note instruction at 0x8030602c that does store relative $r7
and it updates $r7. Whereas in 4.8 similar instruction comes at address
0x80319548 which is after instruction that corrupts saved on stack register.
4.7
---
(gdb) disassemble xhci_check_ trb_in_ td_math trb_in_ td_math: ------- ------- -- ------- ------- -- ------- ------- -- ------- ------- -----
Dump of assembler code for function xhci_check_
0x8030600c <+0>: stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} <---
0x80306010 <+4>: sub sp, #436 ; 0x1b4 <------
0x80306012 <+6>: push {lr} <------
0x80306014 <+8>: bl 0x8000cdcc <__gnu_mcount_nc> <------------------
0x80306018 <+12>: add r7, sp, #432 ; 0x1b0 <------
0x8030601a <+14>: mov r9, r0
0x8030601c <+16>: ldr r1, [r0, #116] ; 0x74
0x8030601e <+18>: add r3, sp, #176 ; 0xb0
0x80306020 <+20>: ldr r2, [r0, #96] ; 0x60
0x80306022 <+22>: movs r0, #0
0x80306024 <+24>: movs r4, #0
0x80306026 <+26>: ldr.w r8, [r1]
0x8030602a <+30>: movs r1, #0
0x8030602c <+32>: strd r0, r1, [r7, #-384]! ; 0x180 <--------------
0x80306030 <+36>: mov r6, r4
0x80306032 <+38>: ldr r2, [r2, #0]
0x80306034 <+40>: ldr.w r1, [r8]
0x80306038 <+44>: str r4, [sp, #40] ; 0x28
0x8030603a <+46>: ldrd r10, r11, [r2, #8]
0x8030603e <+50>: add.w r0, r1, #1008 ; 0x3f0
0x80306042 <+54>: str r1, [sp, #28]
0x80306044 <+56>: str r0, [sp, #44] ; 0x2c
0x80306046 <+58>: ldrd r0, r1, [r8, #8]
0x8030604a <+62>: strd r10, r11, [sp, #32]
0x8030604e <+66>: ldrd r10, r11, [r8, #8]
0x80306052 <+70>: adds r1, #64 ; 0x40
0x80306054 <+72>: ldr r5, [r2, #0]
0x80306056 <+74>: adc.w r0, r0, #0
0x8030605a <+78>: str.w r8, [r3]
0x8030605e <+82>: subs.w r11, r11, #16
0x80306062 <+86>: strd r0, r1, [r3, #112] ; 0x70
0x80306066 <+90>: ldrd r0, r1, [r8, #8]
0x8030606a <+94>: adc.w r10, r10, #4294967295
0x8030606e <+98>: strd r10, r11, [r7, #16] <------
4.8
---
(gdb) disassemble xhci_check_ trb_in_ td_math trb_in_ td_math: ------- ------- -- ------- ------- -- ------- ------- --
Dump of assembler code for function xhci_check_
0x803194e4 <+0>: stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr} <---
0x803194e8 <+4>: sub sp, #444 ; 0x1bc <------
0x803194ea <+6>: push {lr} <------
0x803194ec <+8>: bl 0x8000cc8c <__gnu_mcount_nc> <------------------
0x803194f0 <+12>: mov r9, r0
0x803194f2 <+14>: movs r5, #0
0x803194f4 <+16>: ldr r0, [r0, #116] ; 0x74
0x803194f6 <+18>: mov r11, r5
0x803194f8 <+20>: ldr.w r1, [r9, #96] ; 0x60
0x803194fc <+24>: add.w lr, sp, #184 ; 0xb8
0x80319500 <+28>: str r5, [sp, #32]
0x80319502 <+30>: add r7, sp, #440 ; 0x1b8 <------
0x80319504 <+32>: ldr.w r8, [r0]
0x80319508 <+36>: ldr r0, [r1, #0]
0x8031950a <+38>: str r5, [sp, #36] ; 0x24
0x8031950c <+40>: str r5, [sp, #52] ; 0x34
0x8031950e <+42>: ldrd r4, r5, [r8, #8]
0x80319512 <+46>: ldr r2, [r0, #0]
0x80319514 <+48>: ldr.w r10, [r8]
0x80319518 <+52>: adds.w r3, r5, #64 ; 0x40
0x8031951c <+56>: str.w r8, [lr]
0x80319520 <+60>: str.w ...