#include "Symbols.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Support/raw_ostream.h"
return F->kind() == BitcodeKind;
}
-void BitcodeFile::parse() {
+void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) {
LLVMContext Context;
ErrorOr<std::unique_ptr<IRObjectFile>> ObjOrErr =
IRObjectFile::create(MB, Context);
fatal(ObjOrErr);
IRObjectFile &Obj = **ObjOrErr;
+ const Module &M = Obj.getModule();
+
+ DenseSet<const Comdat *> KeptComdats;
+ for (const auto &P : M.getComdatSymbolTable()) {
+ StringRef N = Saver.save(P.first());
+ if (ComdatGroups.insert(N).second)
+ KeptComdats.insert(&P.second);
+ }
+
for (const BasicSymbolRef &Sym : Obj.symbols()) {
+ if (const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl()))
+ if (const Comdat *C = GV->getComdat())
+ if (!KeptComdats.count(C))
+ continue;
+
SmallString<64> Name;
raw_svector_ostream OS(Name);
Sym.printName(OS);
public:
explicit BitcodeFile(MemoryBufferRef M);
static bool classof(const InputFile *F);
- void parse();
+ void parse(llvm::DenseSet<StringRef> &ComdatGroups);
ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
private:
// LLVM bitcode file.
if (auto *F = dyn_cast<BitcodeFile>(FileP)) {
BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
- F->parse();
+ F->parse(ComdatGroups);
for (SymbolBody *B : F->getSymbols())
resolve(B);
return;
if (BitcodeFiles.empty())
return;
ObjectFile<ELFT> *Obj = createCombinedLtoObject();
- // FIXME: We probably have to ignore comdats here.
- Obj->parse(ComdatGroups);
+ llvm::DenseSet<StringRef> DummyGroups;
+ Obj->parse(DummyGroups);
for (SymbolBody *Body : Obj->getSymbols()) {
Symbol *Sym = insert(Body);
Sym->Body = Body;
--- /dev/null
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.o
+; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
+; RUN: llvm-readobj -t %t.so | FileCheck %s
+
+; CHECK: Name: foo
+; CHECK-NEXT: Value:
+; CHECK-NEXT: Size: 1
+; CHECK-NEXT: Binding: Global
+; CHECK-NEXT: Type: Function
+; CHECK-NEXT: Other: 0
+; CHECK-NEXT: Section: .text
+
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+$foo = comdat any
+define void @foo() comdat {
+ ret void
+}
+