[RTEMS Project] #1889: [ARM] Wrong code in libstdc++
RTEMS trac
trac at rtems.org
Sat Nov 22 15:25:49 UTC 2014
#1889: [ARM] Wrong code in libstdc++
-----------------------------+-----------------------------
Reporter: sebastian.huber | Owner: ralf.corsepius
Type: defect | Status: closed
Priority: normal | Milestone: 4.11
Component: GCC | Version: unknown
Severity: normal | Resolution: duplicate
Keywords: |
-----------------------------+-----------------------------
Changes (by amar):
* milestone: => 4.11
Old description:
> Lets have a look at with comments inside:
>
> objdump -d -C /opt/rtems-4.11/lib/gcc/arm-
> rtems4.11/4.6.1/thumb/vfp/libstdc++.a | grep -A 94 new_opnt.o
>
> new_opnt.o: file format elf32-littlearm
>
> Disassembly of section .text._ZnwmRKSt9nothrow_t:
>
> 00000000 <operator new(unsigned long, std::nothrow_t const&)>:
> 0: b5f0 push {r4, r5, r6, r7, lr}
> 2: 465f mov r7, fp
> 4: 4656 mov r6, sl
> 6: 464d mov r5, r9
> 8: 4644 mov r4, r8
> a: b4f0 push {r4, r5, r6, r7}
> c: b090 sub sp, #64 ; 0x40
> e: 4b2a ldr r3, [pc, #168] ; (b8 <operator
> new(unsigned long, std::nothrow_t const&)+0xb8>)
> 10: af00 add r7, sp, #0
> 12: 627b str r3, [r7, #36] ; 0x24
> 14: 4b29 ldr r3, [pc, #164] ; (bc <operator
> new(unsigned long, std::nothrow_t const&)+0xbc>)
> 16: 62bb str r3, [r7, #40] ; 0x28
> 18: 4b29 ldr r3, [pc, #164] ; (c0 <operator
> new(unsigned long, std::nothrow_t const&)+0xc0>)
> 1a: 6078 str r0, [r7, #4]
> 1c: 2240 movs r2, #64 ; 0x40
> 1e: 1c38 adds r0, r7, #0
> 20: 19d2 adds r2, r2, r7
> 22: 633b str r3, [r7, #48] ; 0x30
> 24: 300c adds r0, #12
> 26: 466b mov r3, sp
> 28: 62fa str r2, [r7, #44] ; 0x2c
> 2a: 637b str r3, [r7, #52] ; 0x34
> 2c: f7ff fffe bl 0 <_Unwind_SjLj_Register>
> 30: 687a ldr r2, [r7, #4]
> 32: 2a00 cmp r2, #0
> 34: d101 bne.n 3a <operator new(unsigned long,
> std::nothrow_t const&)+0x3a>
> 36: 2301 movs r3, #1
> 38: 607b str r3, [r7, #4]
> 3a: 6878 ldr r0, [r7, #4]
> 3c: f7ff fffe bl 0 <malloc>
> 40: 6038 str r0, [r7, #0]
> 42: 2800 cmp r0, #0
> 44: d123 bne.n 8e <operator new(unsigned long,
> std::nothrow_t const&)+0x8e>
> 46: 4a1f ldr r2, [pc, #124] ; (c4 <operator
> new(unsigned long, std::nothrow_t const&)+0xc4>)
> 48: 6813 ldr r3, [r2, #0]
> 4a: 2b00 cmp r3, #0
> 4c: d104 bne.n 58 <operator new(unsigned long,
> std::nothrow_t const&)+0x58>
> 4e: e021 b.n 94 <operator new(unsigned long,
> std::nothrow_t const&)+0x94>
> 50: 4a1c ldr r2, [pc, #112] ; (c4 <operator
> new(unsigned long, std::nothrow_t const&)+0xc4>)
> 52: 6813 ldr r3, [r2, #0]
> 54: 2b00 cmp r3, #0
> 56: d009 beq.n 6c <operator new(unsigned long,
> std::nothrow_t const&)+0x6c>
> 58: 2201 movs r2, #1
> 5a: 613a str r2, [r7, #16]
> 5c: f000 f834 bl c8 <operator new(unsigned long,
> std::nothrow_t const&)+0xc8>
> 60: 6878 ldr r0, [r7, #4]
> 62: f7ff fffe bl 0 <malloc>
> 66: 60b8 str r0, [r7, #8]
> 68: 2800 cmp r0, #0
> 6a: d0f1 beq.n 50 <operator new(unsigned long,
> std::nothrow_t const&)+0x50>
> 6c: 1c38 adds r0, r7, #0
> 6e: 300c adds r0, #12
> 70: f7ff fffe bl 0 <_Unwind_SjLj_Unregister>
>
> BAD CODE BEGIN
>
> 74: 46bd mov sp, r7
>
> r7 is now the current stack pointer.
>
> 76: b010 add sp, #64 ; 0x40
>
> Current stack frame is free now, r7 points to obsolete stack frame.
>
> 78: 68b8 ldr r0, [r7, #8]
>
> Here we read from the stack frame freed previously. This is a disaster
> in multi-threaded environments, because the exception code will use the
> stack of an interrupted thread.
>
> BAD CODE END
>
> 7a: bc3c pop {r2, r3, r4, r5}
> 7c: 4690 mov r8, r2
> 7e: 4699 mov r9, r3
> 80: 46a2 mov sl, r4
> 82: 46ab mov fp, r5
> 84: bdf0 pop {r4, r5, r6, r7, pc}
> 86: f7ff fffe bl 0 <__cxa_begin_catch>
> 8a: f7ff fffe bl 0 <__cxa_end_catch>
> 8e: 683b ldr r3, [r7, #0]
> 90: 60bb str r3, [r7, #8]
> 92: e7eb b.n 6c <operator new(unsigned long,
> std::nothrow_t const&)+0x6c>
> 94: 2200 movs r2, #0
> 96: 60ba str r2, [r7, #8]
> 98: e7e8 b.n 6c <operator new(unsigned long,
> std::nothrow_t const&)+0x6c>
> 9a: 3f40 subs r7, #64 ; 0x40
> 9c: 69bb ldr r3, [r7, #24]
> 9e: 6978 ldr r0, [r7, #20]
> a0: 2b01 cmp r3, #1
> a2: d0f0 beq.n 86 <operator new(unsigned long,
> std::nothrow_t const&)+0x86>
> a4: 1c5a adds r2, r3, #1
> a6: d004 beq.n b2 <operator new(unsigned long,
> std::nothrow_t const&)+0xb2>
> a8: 2301 movs r3, #1
> aa: 425b negs r3, r3
> ac: 613b str r3, [r7, #16]
> ae: f7ff fffe bl 0 <_Unwind_SjLj_Resume>
> b2: 613b str r3, [r7, #16]
> b4: f7ff fffe bl 0 <__cxa_call_unexpected>
> ...
> c0: 0000009a .word 0x0000009a
> c4: 00000000 .word 0x00000000
> c8: 4718 bx r3
> ca: 46c0 nop ; (mov r8, r8)
>
> This problem may be related to GCC bug 38644:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38644
>
> A workaround was here to use the -fno-schedule-insns2 option.
New description:
Lets have a look at with comments inside:
objdump -d -C /opt/rtems-4.11/lib/gcc/arm-
rtems4.11/4.6.1/thumb/vfp/libstdc++.a | grep -A 94 new_opnt.o
new_opnt.o: file format elf32-littlearm
Disassembly of section .text._ZnwmRKSt9nothrow_t:
00000000 <operator new(unsigned long, std::nothrow_t const&)>:
0: b5f0 push {r4, r5, r6, r7, lr}
2: 465f mov r7, fp
4: 4656 mov r6, sl
6: 464d mov r5, r9
8: 4644 mov r4, r8
a: b4f0 push {r4, r5, r6, r7}
c: b090 sub sp, #64 ; 0x40
e: 4b2a ldr r3, [pc, #168] ; (b8 <operator
new(unsigned long, std::nothrow_t const&)+0xb8>)
10: af00 add r7, sp, #0
12: 627b str r3, [r7, #36] ; 0x24
14: 4b29 ldr r3, [pc, #164] ; (bc <operator
new(unsigned long, std::nothrow_t const&)+0xbc>)
16: 62bb str r3, [r7, #40] ; 0x28
18: 4b29 ldr r3, [pc, #164] ; (c0 <operator
new(unsigned long, std::nothrow_t const&)+0xc0>)
1a: 6078 str r0, [r7, #4]
1c: 2240 movs r2, #64 ; 0x40
1e: 1c38 adds r0, r7, #0
20: 19d2 adds r2, r2, r7
22: 633b str r3, [r7, #48] ; 0x30
24: 300c adds r0, #12
26: 466b mov r3, sp
28: 62fa str r2, [r7, #44] ; 0x2c
2a: 637b str r3, [r7, #52] ; 0x34
2c: f7ff fffe bl 0 <_Unwind_SjLj_Register>
30: 687a ldr r2, [r7, #4]
32: 2a00 cmp r2, #0
34: d101 bne.n 3a <operator new(unsigned long,
std::nothrow_t const&)+0x3a>
36: 2301 movs r3, #1
38: 607b str r3, [r7, #4]
3a: 6878 ldr r0, [r7, #4]
3c: f7ff fffe bl 0 <malloc>
40: 6038 str r0, [r7, #0]
42: 2800 cmp r0, #0
44: d123 bne.n 8e <operator new(unsigned long,
std::nothrow_t const&)+0x8e>
46: 4a1f ldr r2, [pc, #124] ; (c4 <operator
new(unsigned long, std::nothrow_t const&)+0xc4>)
48: 6813 ldr r3, [r2, #0]
4a: 2b00 cmp r3, #0
4c: d104 bne.n 58 <operator new(unsigned long,
std::nothrow_t const&)+0x58>
4e: e021 b.n 94 <operator new(unsigned long,
std::nothrow_t const&)+0x94>
50: 4a1c ldr r2, [pc, #112] ; (c4 <operator
new(unsigned long, std::nothrow_t const&)+0xc4>)
52: 6813 ldr r3, [r2, #0]
54: 2b00 cmp r3, #0
56: d009 beq.n 6c <operator new(unsigned long,
std::nothrow_t const&)+0x6c>
58: 2201 movs r2, #1
5a: 613a str r2, [r7, #16]
5c: f000 f834 bl c8 <operator new(unsigned long,
std::nothrow_t const&)+0xc8>
60: 6878 ldr r0, [r7, #4]
62: f7ff fffe bl 0 <malloc>
66: 60b8 str r0, [r7, #8]
68: 2800 cmp r0, #0
6a: d0f1 beq.n 50 <operator new(unsigned long,
std::nothrow_t const&)+0x50>
6c: 1c38 adds r0, r7, #0
6e: 300c adds r0, #12
70: f7ff fffe bl 0 <_Unwind_SjLj_Unregister>
BAD CODE BEGIN
74: 46bd mov sp, r7
r7 is now the current stack pointer.
76: b010 add sp, #64 ; 0x40
Current stack frame is free now, r7 points to obsolete stack frame.
78: 68b8 ldr r0, [r7, #8]
Here we read from the stack frame freed previously. This is a disaster in
multi-threaded environments, because the exception code will use the stack
of an interrupted thread.
BAD CODE END
7a: bc3c pop {r2, r3, r4, r5}
7c: 4690 mov r8, r2
7e: 4699 mov r9, r3
80: 46a2 mov sl, r4
82: 46ab mov fp, r5
84: bdf0 pop {r4, r5, r6, r7, pc}
86: f7ff fffe bl 0 <__cxa_begin_catch>
8a: f7ff fffe bl 0 <__cxa_end_catch>
8e: 683b ldr r3, [r7, #0]
90: 60bb str r3, [r7, #8]
92: e7eb b.n 6c <operator new(unsigned long,
std::nothrow_t const&)+0x6c>
94: 2200 movs r2, #0
96: 60ba str r2, [r7, #8]
98: e7e8 b.n 6c <operator new(unsigned long,
std::nothrow_t const&)+0x6c>
9a: 3f40 subs r7, #64 ; 0x40
9c: 69bb ldr r3, [r7, #24]
9e: 6978 ldr r0, [r7, #20]
a0: 2b01 cmp r3, #1
a2: d0f0 beq.n 86 <operator new(unsigned long,
std::nothrow_t const&)+0x86>
a4: 1c5a adds r2, r3, #1
a6: d004 beq.n b2 <operator new(unsigned long,
std::nothrow_t const&)+0xb2>
a8: 2301 movs r3, #1
aa: 425b negs r3, r3
ac: 613b str r3, [r7, #16]
ae: f7ff fffe bl 0 <_Unwind_SjLj_Resume>
b2: 613b str r3, [r7, #16]
b4: f7ff fffe bl 0 <__cxa_call_unexpected>
...
c0: 0000009a .word 0x0000009a
c4: 00000000 .word 0x00000000
c8: 4718 bx r3
ca: 46c0 nop ; (mov r8, r8)
This problem may be related to GCC bug 38644:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38644
A workaround was here to use the -fno-schedule-insns2 option.
--
Comment:
Set milestone.
--
Ticket URL: <http://devel.rtems.org/ticket/1889#comment:2>
RTEMS Project <http://www.rtems.org/>
RTEMS Project
More information about the bugs
mailing list