[LTO] Include in .symtab/.dynsym symbols introduced by optimizations.
authorDavide Italiano <davide@freebsd.org>
Tue, 29 Mar 2016 00:15:52 +0000 (00:15 +0000)
committerDavide Italiano <davide@freebsd.org>
Tue, 29 Mar 2016 00:15:52 +0000 (00:15 +0000)
Some optimizations, e.g. SimplifyLibCalls, can replace functions with
others as part of the lowering, e.g. printf => puts.
The new symbols don't have the isUsedInRegularObj flag set so they
don't get included in the final symbol table (and dynamic symbol
table), and the dynamic linker gets confused. Include  them as a fix.

Differential Revision: http://reviews.llvm.org/D18357

llvm-svn: 264688

lld/ELF/SymbolTable.cpp
lld/ELF/Symbols.h
lld/test/ELF/lto/Inputs/shared.s [new file with mode: 0644]
lld/test/ELF/lto/undefined-puts.ll [new file with mode: 0644]

index dd11406..017ac83 100644 (file)
@@ -108,6 +108,7 @@ template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() {
   Obj->parse(DummyGroups);
   for (SymbolBody *Body : Obj->getNonLocalSymbols()) {
     Symbol *Sym = insert(Body);
+    Sym->Body->setUsedInRegularObj();
     if (!Sym->Body->isUndefined() && Body->isUndefined())
       continue;
     Sym->Body = Body;
index f316f83..8db6e22 100644 (file)
@@ -89,6 +89,8 @@ public:
   bool isInGot() const { return GotIndex != -1U; }
   bool isInPlt() const { return PltIndex != -1U; }
 
+  void setUsedInRegularObj() { IsUsedInRegularObj = true; }
+
   template <class ELFT>
   typename ELFT::uint getVA(typename ELFT::uint Addend = 0) const;
 
@@ -319,7 +321,6 @@ public:
   std::unique_ptr<InputFile> getMember();
 
   void setWeak() { IsWeak = true; }
-  void setUsedInRegularObj() { IsUsedInRegularObj = true; }
 
 private:
   ArchiveFile *File;
diff --git a/lld/test/ELF/lto/Inputs/shared.s b/lld/test/ELF/lto/Inputs/shared.s
new file mode 100644 (file)
index 0000000..d1ef371
--- /dev/null
@@ -0,0 +1,5 @@
+.globl  printf
+printf:
+
+.globl  puts
+puts:
diff --git a/lld/test/ELF/lto/undefined-puts.ll b/lld/test/ELF/lto/undefined-puts.ll
new file mode 100644 (file)
index 0000000..3216ff4
--- /dev/null
@@ -0,0 +1,28 @@
+; REQUIRES: x86
+; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux
+; RUN: ld.lld %t1.o -o %t1.so -shared
+; RUN: llvm-as %s -o %t2.o
+; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t
+; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@.str = private unnamed_addr constant [6 x i8] c"blah\0A\00", align 1
+
+define i32 @_start() {
+  %str = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
+  ret i32 0
+}
+
+declare i32 @printf(i8*, ...)
+
+; Check that puts symbol is present in the dynamic symbol table and
+; there's a relocation for it.
+; CHECK: Dynamic Relocations {
+; CHECK-NEXT:  0x11007 R_X86_64_PC32 puts 0xFFFFFFFFFFFFFFFC
+; CHECK-NEXT: }
+
+; CHECK: DynamicSymbols [
+; CHECK: Symbol {
+; CHECK:    Name: puts@