[LLVMbugs] [Bug 16959] New: [-cxx-abi microsoft] dynamic initializers for linkonce_odr data run twice when linking clang and MSVC code

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Wed Aug 21 13:28:25 PDT 2013


http://llvm.org/bugs/show_bug.cgi?id=16959

            Bug ID: 16959
           Summary: [-cxx-abi microsoft] dynamic initializers for
                    linkonce_odr data run twice when linking clang and
                    MSVC code
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: Common Code Generator Code
          Assignee: unassignedbugs at nondot.org
          Reporter: rnk at google.com
                CC: llvmbugs at cs.uiuc.edu
        Depends on: 16888
            Blocks: 12477
    Classification: Unclassified

Created attachment 11080
  --> http://llvm.org/bugs/attachment.cgi?id=11080&action=edit
double initialization test case

The attached test case fails when built with and without -DCONFIG_1 while
mixing compilers.

The Microsoft ABI does *not* use guard variables to avoid double initialization
of linkonce_odr data, but my fix for PR16888 does.

What's supposed to happen is something like the following:

---

.CRT$XCU is a section similar to .init_array on Linux / ELF, an array of void
function pointers.

Each TU with a weak initializer emits two symbols:
  void ("?__E" <data>)(void)
  void (* <data> "$initializer$")(void)

The __E symbol is the initializer code stub goes into the usual COMDAT
selectany text section, the way we would emit any inline function.

The $initializer$ symbol goes into a .CRT$XCU COMDAT section with the
IMAGE_COMDAT_SELECT_ASSOCIATIVE flag, where it is associated with the __E
symbol.

This way, the linker picks one __E symbol, and then throws away all the
associated function pointers that would have referenced it, thereby leaving
only one call to the initializer.

---

Currently clang orders initializers within a TU by creating one giant function
(__GLOBAL_I_a etc) that calls each initializer stub in turn.  This means that
we can't perform COMDAT elimination on the function pointers in .CRT$XCU.

The LLVM LangRef says that initializers in llvm.global_ctors with the same
priority are not ordered, but I wonder if we could loosen that initializers
with the same priority in a single TU are called in the order defined by the
global_ctors array.

With that change, I don't think clang would need to emit __GLOBAL_I_*
functions.  Are there any known object file formats or platforms where the
linker would violate that guarantee?

-- 
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/20130821/4bc2249e/attachment.html>


More information about the llvm-bugs mailing list