Index: llvm/lib/Target/X86/X86TargetMachine.cpp =================================================================== --- llvm/lib/Target/X86/X86TargetMachine.cpp +++ llvm/lib/Target/X86/X86TargetMachine.cpp @@ -100,8 +100,10 @@ return std::make_unique(); if (TT.isOSFuchsia()) return std::make_unique(); - if (TT.isOSBinFormatELF()) + if (TT.isOSNetBSD()) return std::make_unique(); + if (TT.isOSBinFormatELF()) + return std::make_unique(); if (TT.isOSBinFormatCOFF()) return std::make_unique(); llvm_unreachable("unknown subtarget type"); Index: llvm/lib/Target/X86/X86TargetObjectFile.h =================================================================== --- llvm/lib/Target/X86/X86TargetObjectFile.h +++ llvm/lib/Target/X86/X86TargetObjectFile.h @@ -49,6 +49,12 @@ const MCExpr *getDebugThreadLocalSymbol(const MCSymbol *Sym) const override; }; + /// X86BinFormatELFTargetObjectFile - This implementation is used for OS + /// which uses ELF Binary Format on x86 and x86-64. + class X86BinFormatELFTargetObjectFile : public X86ELFTargetObjectFile { + void Initialize(MCContext &Ctx, const TargetMachine &TM) override; + }; + /// X86FreeBSDTargetObjectFile - This implementation is used for FreeBSD /// on x86 and x86-64. class X86FreeBSDTargetObjectFile : public X86ELFTargetObjectFile { Index: llvm/lib/Target/X86/X86TargetObjectFile.cpp =================================================================== --- llvm/lib/Target/X86/X86TargetObjectFile.cpp +++ llvm/lib/Target/X86/X86TargetObjectFile.cpp @@ -64,6 +64,13 @@ return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_DTPOFF, getContext()); } +void +X86BinFormatELFTargetObjectFile::Initialize(MCContext &Ctx, + const TargetMachine &TM) { + TargetLoweringObjectFileELF::Initialize(Ctx, TM); + InitializeELF(TM.Options.UseInitArray); +} + void X86FreeBSDTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { Index: llvm/test/CodeGen/X86/init-array.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/init-array.ll @@ -0,0 +1,37 @@ +; RUN: llc < %s -mtriple=x86_64 -use-ctors=false | FileCheck %s + +; Check that our compiler emits global constructors +; inside the .init_array section + + +%class.B = type { i32 } + +$_ZN1BC2Ei = comdat any + +@b = dso_local global %class.B zeroinitializer, align 4 +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_p1.cc, i8* null }] +define internal void @__cxx_global_var_init() { +entry: + call void @_ZN1BC2Ei(%class.B* @b, i32 1) + ret void +} + +define linkonce_odr dso_local void @_ZN1BC2Ei(%class.B* %this, i32 %t) unnamed_addr comdat align 2 { +entry: + %this.addr = alloca %class.B*, align 8 + %t.addr = alloca i32, align 4 + store %class.B* %this, %class.B** %this.addr, align 8 + store i32 %t, i32* %t.addr, align 4 + %this1 = load %class.B*, %class.B** %this.addr, align 8 + %0 = load i32, i32* %t.addr, align 4 + %j = getelementptr inbounds %class.B, %class.B* %this1, i32 0, i32 0 + store i32 %0, i32* %j, align 4 + ret void +} +define internal void @_GLOBAL__sub_I_p1.cc() { +entry: + call void @__cxx_global_var_init() + ret void +} + +; CHECK: .init_array