From b1b5cc83f1090f91a320b079282e22df2ea77ad5 Mon Sep 17 00:00:00 2001 From: Sean Silva Date: Fri, 11 Mar 2016 00:50:05 +0000 Subject: [PATCH] [lto] Make sure that ctors are added to the combined module. Summary: More generally, appending linkage is a special case that we don't want to create a SymbolBody for. Reviewers: rafael, ruiu Subscribers: Bigcheese, llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D18012 llvm-svn: 263179 --- lld/ELF/InputFiles.cpp | 4 +++- lld/ELF/InputFiles.h | 8 ++++++++ lld/ELF/SymbolTable.cpp | 5 +++++ lld/test/ELF/lto/ctors.ll | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/lto/ctors.ll diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 2272963e43c5..a4757b1b4056 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -450,8 +450,10 @@ void BitcodeFile::parse(DenseSet &ComdatGroups) { continue; if (!(Flags & BasicSymbolRef::SF_Global)) continue; - if (Flags & BasicSymbolRef::SF_FormatSpecific) + if (GV->hasAppendingLinkage()) { + ExtraKeeps.push_back(GV->getName().copy(Alloc)); continue; + } uint8_t Visibility = getGvVisibility(GV); SmallString<64> Name; diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 48fe27d31f2d..94d0a3767603 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -185,9 +185,17 @@ public: static bool classof(const InputFile *F); void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return SymbolBodies; } + ArrayRef getExtraKeeps() { return ExtraKeeps; } private: std::vector SymbolBodies; + // Some symbols like llvm.global_ctors are internal to the IR and so + // don't show up in SymbolBodies, but must be kept when creating the + // combined LTO module. We track them here. + // We currently use a different Module for creating SymbolBody's vs when + // we are creating the combined LTO module, and so we can't store IR + // pointers directly and must rely on the IR names. + std::vector ExtraKeeps; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver{Alloc}; }; diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index a5a88a09b484..cdff124b6920 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -155,6 +155,11 @@ static void addBitcodeFile(IRMover &Mover, BitcodeFile &F, assert(GV); Keep.push_back(GV); } + for (StringRef S : F.getExtraKeeps()) { + GlobalValue *GV = M->getNamedValue(S); + assert(GV); + Keep.push_back(GV); + } Mover.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {}); } diff --git a/lld/test/ELF/lto/ctors.ll b/lld/test/ELF/lto/ctors.ll new file mode 100644 index 000000000000..629e503f474a --- /dev/null +++ b/lld/test/ELF/lto/ctors.ll @@ -0,0 +1,15 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-readobj -sections %t.so | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] +define void @ctor() { + ret void +} + +; The llvm.global_ctors should end up producing constructors. +; CHECK: Name: .ctors