<html>
<head>
<base href="https://bugs.llvm.org/">
</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 - misoptimizing EMPTY_STACK was placed into .rodata"
href="https://bugs.llvm.org/show_bug.cgi?id=38911">38911</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>misoptimizing EMPTY_STACK was placed into .rodata
</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>Linux
</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>Common Code Generator Code
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>zhaixiang@loongson.cn
</td>
</tr>
<tr>
<th>CC</th>
<td>llvm-bugs@lists.llvm.org
</td>
</tr></table>
<p>
<div>
<pre>Hi LLVM developers,
The reduced testcase provided by Dimitry Andric is:
$ cat JDK-8205969.cpp
#include <new>
class NativeCallStack {
public:
static const NativeCallStack EMPTY_STACK;
private:
enum { DEPTH = 4 };
void* stack[DEPTH];
public:
NativeCallStack() {
for (int i = 0; i < DEPTH; ++i) {
stack[i] = nullptr;
}
}
};
const NativeCallStack NativeCallStack::EMPTY_STACK;
int main(void)
{
// The following should segfault, if EMPTY_STACK was placed into .rodata.
::new ((void*)&NativeCallStack::EMPTY_STACK) NativeCallStack();
return 0;
}
----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< ---
It is able to reproduce after compiled with clang-8 optimized for X86:
$ clang++ -O3 -S -c JDK-8205969.cpp -o JDK-8205969-opt-8.0.s
$ clang++ -O3 -c JDK-8205969.cpp -o JDK-8205969-opt-8.0.o
$ clang++ -o JDK-8205969-opt-8.0.out JDK-8205969-opt-8.0.o
$ ./JDK-8205969-opt-8.0.out
Segmentation fault
$ cat JDK-8205969-opt-8.0.s
.text
.file "JDK-8205969.cpp"
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.cfi_startproc
# %bb.0:
xorps %xmm0, %xmm0
movups %xmm0, _ZN15NativeCallStack11EMPTY_STACKE+16(%rip)
movups %xmm0, _ZN15NativeCallStack11EMPTY_STACKE(%rip)
xorl %eax, %eax
retq
.Lfunc_end0:
.size main, .Lfunc_end0-main
.cfi_endproc
# -- End function
.type _ZN15NativeCallStack11EMPTY_STACKE,@object #
@_ZN15NativeCallStack11EMPTY_STACKE
.section .rodata,"a",@progbits
^--- READ-ONLY segment
.globl _ZN15NativeCallStack11EMPTY_STACKE
.p2align 3
_ZN15NativeCallStack11EMPTY_STACKE:
.zero 32
.size _ZN15NativeCallStack11EMPTY_STACKE, 32
.ident "LLVM China clang version 8.0.0
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/clang.git 81ef98628ebf5186d746c0986dcbf5073e842043)
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/llvm.git e1aac9723d55497e74d83d216329f08d9842e494)
(based on LLVM 8.0.0svn)"
.section ".note.GNU-stack","",@progbits
.addrsig
----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< ---
But it is *not* able to reproduce with clang-8 not optimized for X86:
$ clang++ -O0 -S -c JDK-8205969.cpp -o JDK-8205969-unopt-8.0.s
$ clang++ -O0 -c JDK-8205969.cpp -o JDK-8205969-unopt-8.0.o
$ clang++ -o JDK-8205969-unopt-8.0.out JDK-8205969-unopt-8.0.o
$ ./JDK-8205969-unopt-8.0.out
No segfault
$ cat JDK-8205969-unopt-8.0.s
.text
.file "JDK-8205969.cpp"
.section .text.startup,"ax",@progbits
.p2align 4, 0x90 # -- Begin function
__cxx_global_var_init
.type __cxx_global_var_init,@function
__cxx_global_var_init: # @__cxx_global_var_init
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movabsq $_ZN15NativeCallStack11EMPTY_STACKE, %rdi
callq _ZN15NativeCallStackC2Ev
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end0:
.size __cxx_global_var_init, .Lfunc_end0-__cxx_global_var_init
.cfi_endproc
# -- End function
.section
.text._ZN15NativeCallStackC2Ev,"axG",@progbits,_ZN15NativeCallStackC2Ev,comdat
.weak _ZN15NativeCallStackC2Ev # -- Begin function
_ZN15NativeCallStackC2Ev
.p2align 4, 0x90
.type _ZN15NativeCallStackC2Ev,@function
_ZN15NativeCallStackC2Ev: # @_ZN15NativeCallStackC2Ev
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rdi
movl $0, -12(%rbp)
movq %rdi, -24(%rbp) # 8-byte Spill
.LBB1_1: # =>This Inner Loop Header: Depth=1
cmpl $4, -12(%rbp)
jge .LBB1_4
# %bb.2: # in Loop: Header=BB1_1 Depth=1
movslq -12(%rbp), %rax
movq -24(%rbp), %rcx # 8-byte Reload
movq $0, (%rcx,%rax,8)
# %bb.3: # in Loop: Header=BB1_1 Depth=1
movl -12(%rbp), %eax
addl $1, %eax
movl %eax, -12(%rbp)
jmp .LBB1_1
.LBB1_4:
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end1:
.size _ZN15NativeCallStackC2Ev, .Lfunc_end1-_ZN15NativeCallStackC2Ev
.cfi_endproc
# -- End function
.text
.globl main # -- Begin function main
.p2align 4, 0x90
.type main,@function
main: # @main
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
movl $0, -4(%rbp)
movabsq $_ZN15NativeCallStack11EMPTY_STACKE, %rdi
callq _ZN15NativeCallStackC2Ev
xorl %eax, %eax
addq $16, %rsp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end2:
.size main, .Lfunc_end2-main
.cfi_endproc
# -- End function
.section .text.startup,"ax",@progbits
.p2align 4, 0x90 # -- Begin function
_GLOBAL__sub_I_JDK_8205969.cpp
.type _GLOBAL__sub_I_JDK_8205969.cpp,@function
_GLOBAL__sub_I_JDK_8205969.cpp: # @_GLOBAL__sub_I_JDK_8205969.cpp
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
callq __cxx_global_var_init
popq %rbp
.cfi_def_cfa %rsp, 8
retq
.Lfunc_end3:
.size _GLOBAL__sub_I_JDK_8205969.cpp,
.Lfunc_end3-_GLOBAL__sub_I_JDK_8205969.cpp
.cfi_endproc
# -- End function
.type _ZN15NativeCallStack11EMPTY_STACKE,@object #
@_ZN15NativeCallStack11EMPTY_STACKE
.bss
^--- R/W segment
.globl _ZN15NativeCallStack11EMPTY_STACKE
.p2align 3
_ZN15NativeCallStack11EMPTY_STACKE:
.zero 32
.size _ZN15NativeCallStack11EMPTY_STACKE, 32
.section .init_array,"aw",@init_array
.p2align 3
.quad _GLOBAL__sub_I_JDK_8205969.cpp
.ident "LLVM China clang version 8.0.0
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/clang.git 81ef98628ebf5186d746c0986dcbf5073e842043)
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/llvm.git e1aac9723d55497e74d83d216329f08d9842e494)
(based on LLVM 8.0.0svn)"
.section ".note.GNU-stack","",@progbits
.addrsig
.addrsig_sym __cxx_global_var_init
.addrsig_sym _GLOBAL__sub_I_JDK_8205969.cpp
.addrsig_sym _ZN15NativeCallStack11EMPTY_STACKE
----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< ---
Furthermore clang-3.9.1 *optimized* for X86 is *not* able to reproduce the
issue neither. It behaviors like gcc-6.4.1 and gcc-8. And clang-8 -O3 for
mips64el is also able to reproduce this issue:
.text
.abicalls
.section .mdebug.abi64,"",@progbits
.nan legacy
.file "t.cpp"
.text
.globl main
.p2align 3
.type main,@function
.set nomicromips
.set nomips16
.ent main
main:
.frame $sp,0,$ra
.mask 0x00000000,0
.fmask 0x00000000,0
.set noreorder
.set nomacro
.set noat
lui $1, %hi(%neg(%gp_rel(main)))
daddiu $2, $zero, 0
daddu $1, $1, $25
daddiu $1, $1, %lo(%neg(%gp_rel(main)))
ld $1, %got_disp(_ZN15NativeCallStack11EMPTY_STACKE)($1)
sd $zero, 24($1)
sd $zero, 16($1)
sd $zero, 8($1)
jr $ra
sd $zero, 0($1)
.set at
.set macro
.set reorder
.end main
.Lfunc_end0:
.size main, .Lfunc_end0-main
.type _ZN15NativeCallStack11EMPTY_STACKE,@object
.section .rodata,"a",@progbits
^--- READ-ONLY segment
.globl _ZN15NativeCallStack11EMPTY_STACKE
.p2align 3
_ZN15NativeCallStack11EMPTY_STACKE:
.space 32
.size _ZN15NativeCallStack11EMPTY_STACKE, 32
.ident "Loongson clang version 8.0.0
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/clang.git 7b2e28d9d836a5727000b3279b83ff59acddcae2)
(<a href="mailto:git@github.com">git@github.com</a>:llvm-mirror/llvm.git 997088e42d6a8f323fa0dd4065579d12c7b64b4f)
(based on LLVM 8.0.0svn)"
.section ".note.GNU-stack","",@progbits
.text
----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< ---
Monkey patch is:
$ cat monkey.patch
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 7a5fd29..5d3dc6a 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -564,7 +564,7 @@ static StringRef getSectionPrefixForGlobal(SectionKind
Kind) {
if (Kind.isText())
return ".text";
if (Kind.isReadOnly())
- return ".rodata";
+ return ".bss";
if (Kind.isBSS())
return ".bss";
if (Kind.isThreadData())
----- 8< -------- 8< -------- 8< -------- 8< -------- 8< -------- 8< ---
So perhaps it is better to double check the setter of isReadOnly() Thanks!
<a href="http://lists.llvm.org/pipermail/llvm-dev/2018-September/125952.html">http://lists.llvm.org/pipermail/llvm-dev/2018-September/125952.html</a>
<a href="https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225054#c8">https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225054#c8</a>
<a href="https://bugs.openjdk.java.net/browse/JDK-8205965">https://bugs.openjdk.java.net/browse/JDK-8205965</a>
Regards,
Leslie Zhai</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>