[llvm-bugs] [Bug 38911] New: misoptimizing EMPTY_STACK was placed into .rodata

via llvm-bugs llvm-bugs at lists.llvm.org
Wed Sep 12 04:04:22 PDT 2018


https://bugs.llvm.org/show_bug.cgi?id=38911

            Bug ID: 38911
           Summary: misoptimizing EMPTY_STACK was placed into .rodata
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: zhaixiang at loongson.cn
                CC: llvm-bugs at lists.llvm.org

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, at 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, at object #
@_ZN15NativeCallStack11EMPTY_STACKE
        .section        .rodata,"a", at 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
(git at github.com:llvm-mirror/clang.git 81ef98628ebf5186d746c0986dcbf5073e842043)
(git at github.com:llvm-mirror/llvm.git e1aac9723d55497e74d83d216329f08d9842e494)
(based on LLVM 8.0.0svn)"
        .section        ".note.GNU-stack","", at 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", at progbits
        .p2align        4, 0x90         # -- Begin function
__cxx_global_var_init
        .type   __cxx_global_var_init, at 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", at progbits,_ZN15NativeCallStackC2Ev,comdat
        .weak   _ZN15NativeCallStackC2Ev # -- Begin function
_ZN15NativeCallStackC2Ev
        .p2align        4, 0x90
        .type   _ZN15NativeCallStackC2Ev, at 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, at 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", at progbits
        .p2align        4, 0x90         # -- Begin function
_GLOBAL__sub_I_JDK_8205969.cpp
        .type   _GLOBAL__sub_I_JDK_8205969.cpp, at 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, at object #
@_ZN15NativeCallStack11EMPTY_STACKE
        .bss

        ^--- R/W segment

        .globl  _ZN15NativeCallStack11EMPTY_STACKE
        .p2align        3
_ZN15NativeCallStack11EMPTY_STACKE:
        .zero   32
        .size   _ZN15NativeCallStack11EMPTY_STACKE, 32

        .section        .init_array,"aw", at init_array
        .p2align        3
        .quad   _GLOBAL__sub_I_JDK_8205969.cpp

        .ident  "LLVM China clang version 8.0.0
(git at github.com:llvm-mirror/clang.git 81ef98628ebf5186d746c0986dcbf5073e842043)
(git at github.com:llvm-mirror/llvm.git e1aac9723d55497e74d83d216329f08d9842e494)
(based on LLVM 8.0.0svn)"
        .section        ".note.GNU-stack","", at 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,"", at progbits
        .nan    legacy
        .file   "t.cpp"
        .text
        .globl  main
        .p2align        3
        .type   main, at 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, at object
        .section        .rodata,"a", at progbits
                        ^--- READ-ONLY segment
        .globl  _ZN15NativeCallStack11EMPTY_STACKE
        .p2align        3
_ZN15NativeCallStack11EMPTY_STACKE:
        .space  32
        .size   _ZN15NativeCallStack11EMPTY_STACKE, 32


        .ident  "Loongson clang version 8.0.0
(git at github.com:llvm-mirror/clang.git 7b2e28d9d836a5727000b3279b83ff59acddcae2)
(git at github.com:llvm-mirror/llvm.git 997088e42d6a8f323fa0dd4065579d12c7b64b4f)
(based on LLVM 8.0.0svn)"
        .section        ".note.GNU-stack","", at 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!

http://lists.llvm.org/pipermail/llvm-dev/2018-September/125952.html
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225054#c8
https://bugs.openjdk.java.net/browse/JDK-8205965

Regards,
Leslie Zhai

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20180912/eb4529ee/attachment-0001.html>


More information about the llvm-bugs mailing list