<html>
<head>
<base href="https://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - stack smash protection epilogue code incorrectly associated with inlined body"
href="https://llvm.org/bugs/show_bug.cgi?id=27829">27829</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>stack smash protection epilogue code incorrectly associated with inlined body
</td>
</tr>
<tr>
<th>Product</th>
<td>libraries
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Windows NT
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>DebugInfo
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>warren_ristow@playstation.sony.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Compiling the test-case at the end of this description as:
clang++ -c -g -O2 -fstack-protector-strong test.cpp
shows a problem where the Stack Smash Protection code in the epilogue of
'main()' is incorrectly associated with the inlined body of 'bar()'. In the
example, 'main()' calls 'foo()', which calls 'bar()' 3 times (all of these
calls are inlined into 'main()').
Running 'llvm-dwarfdump' on "test.o" created as above, shows 3
DW_TAG_inlined_subroutine entries for 'bar()':
0x000000dc: DW_TAG_inlined_subroutine [11]
...
DW_AT_low_pc [DW_FORM_addr] (0x000000000000004c)
DW_AT_high_pc [DW_FORM_data4] (0x0000000c)
...
0x000000ef: DW_TAG_inlined_subroutine [11]
...
DW_AT_low_pc [DW_FORM_addr] (0x0000000000000058)
DW_AT_high_pc [DW_FORM_data4] (0x0000000c)
...
0x00000102: DW_TAG_inlined_subroutine [11]
...
DW_AT_low_pc [DW_FORM_addr] (0x0000000000000064)
DW_AT_high_pc [DW_FORM_data4] (0x0000001c)
...
The first two have 12 (0xc) bytes in them, whereas the last one shows 28
(0x1c) bytes. Those additional 16 bytes of code are actually part of the
stack smash protection check in the epilogue of 'main()'. The disassembly
of 'main()', annotated to show the relevant area, is:
0000000000000030 <main>:
30: 48 83 ec 18 sub $0x18,%rsp
34: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
3b: 00 00
3d: 48 89 44 24 10 mov %rax,0x10(%rsp)
42: 48 8d 7c 24 08 lea 0x8(%rsp),%rdi
47: e8 d4 ff ff ff callq 20 <_Z4initPi>
Start of 1st inlined call to 'bar()'
4c: 83 05 00 00 00 00 2a addl $0x2a,0x0(%rip) # 53 <main+0x23>
53: e8 a8 ff ff ff callq 0 <_Z7printItv>
End of 1st inlined call to 'bar()'
Start of 2nd inlined call to 'bar()'
58: 83 05 00 00 00 00 2a addl $0x2a,0x0(%rip) # 5f <main+0x2f>
5f: e8 9c ff ff ff callq 0 <_Z7printItv>
End of 2nd inlined call to 'bar()'
Start of 3rd inlined call to 'bar()'
64: 83 05 00 00 00 00 2a addl $0x2a,0x0(%rip) # 6b <main+0x3b>
6b: e8 90 ff ff ff callq 0 <_Z7printItv>
>>> 70: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax
>>> 77: 00 00
>>> 79: 48 3b 44 24 10 cmp 0x10(%rsp),%rax
>>> 7e: 75 07 jne 87 <main+0x57>
End of 3rd inlined call to 'bar()'
80: 31 c0 xor %eax,%eax
82: 48 83 c4 18 add $0x18,%rsp
86: c3 retq
87: e8 00 00 00 00 callq 8c <main+0x5c>
The area marked with '>>>' is part of the epilogue of 'main()', but it's
identified as part of the inlined body of the 3rd call to 'bar()'.
This was found in a reasonably modern x86_64 Linux compiler (r269832), but
the behavior isn't new (also tested with an llvm 3.6 based compiler, which
shows the same behavior).
"test.cpp" is below.
___________________________________________________________________
// clang++ -c -g -O2 -fstack-protector-strong test.cpp
extern "C" int printf(const char *, ...);
extern void __attribute__((noinline)) init(int *p);
extern void __attribute__((noinline)) printIt();
static int glb = 17;
void __attribute__((noinline)) printIt() { // line 7
printf("glb = %d\n", glb); // line 8
}
void __attribute__((noinline)) init(int *p) { // line 11
*p = 1; // line 12
}
static void __attribute__((always_inline)) bar() {
glb += 42; // line 16
printIt(); // line 17
}
static void __attribute__((always_inline)) foo() {
bar(); // line 21
bar(); // line 22
bar(); // line 23
}
int main() {
int array[2]; // Just to force SSP check in 'main()'.
init(array); // line 28
foo(); // line 30
return 0;
}</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>