[lld] r191467 - [ELF] Add COPY relocations.

Michael J. Spencer bigcheesegs at gmail.com
Thu Sep 26 15:09:16 PDT 2013


Author: mspencer
Date: Thu Sep 26 17:09:16 2013
New Revision: 191467

URL: http://llvm.org/viewvc/llvm-project?rev=191467&view=rev
Log:
[ELF] Add COPY relocations.

Added:
    lld/trunk/test/elf/Inputs/libundef.so
    lld/trunk/test/elf/Inputs/undef-from-main-so.c
    lld/trunk/test/elf/Inputs/undef-from-main.c
    lld/trunk/test/elf/Inputs/undef.o
    lld/trunk/test/elf/undef-from-main-dso.test
      - copied, changed from r191466, lld/trunk/test/missing/undef-from-main-dso.test
Removed:
    lld/trunk/test/missing/undef-from-main-dso.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Atoms.h
    lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
    lld/trunk/test/elf/dynamic.test

Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=191467&r1=191466&r2=191467&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Thu Sep 26 17:09:16 2013
@@ -796,6 +796,37 @@ private:
   const Elf_Sym *_symbol;
 };
 
+/// \brief Atom which represents an object for which a COPY relocation will be
+///   generated.
+class ObjectAtom : public SimpleDefinedAtom {
+public:
+  ObjectAtom(const File &f) : SimpleDefinedAtom(f) {}
+
+  virtual Scope scope() const { return scopeGlobal; }
+
+  virtual SectionChoice sectionChoice() const { return sectionBasedOnContent; }
+
+  virtual ContentType contentType() const { return typeZeroFill; }
+
+  virtual uint64_t size() const { return _size; }
+
+  virtual ContentPermissions permissions() const { return permRW_; }
+
+  virtual ArrayRef<uint8_t> rawContent() const {
+    return ArrayRef<uint8_t>();
+  }
+
+  virtual Alignment alignment() const {
+    // The alignment should be 8 byte aligned
+    return Alignment(3);
+  }
+
+  virtual StringRef name() const { return _name; }
+
+  std::string _name;
+  uint64_t _size;
+};
+
 class GOTAtom : public SimpleDefinedAtom {
   StringRef _section;
 

Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=191467&r1=191466&r2=191467&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Sep 26 17:09:16 2013
@@ -770,7 +770,11 @@ template <class ELFT>
 void SymbolTable<ELFT>::addSharedLibAtom(Elf_Sym &sym,
                                          const SharedLibraryAtom *aa) {
   unsigned char binding = 0, type = 0;
-  type = llvm::ELF::STT_FUNC;
+  if (aa->type() == SharedLibraryAtom::Type::Data) {
+    type = llvm::ELF::STT_OBJECT;
+    sym.st_size = aa->size();
+  } else
+    type = llvm::ELF::STT_FUNC;
   sym.st_shndx = llvm::ELF::SHN_UNDEF;
   binding = llvm::ELF::STB_GLOBAL;
   sym.setBindingAndType(binding, type);

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp?rev=191467&r1=191466&r2=191467&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp Thu Sep 26 17:09:16 2013
@@ -89,6 +89,9 @@ template <class Derived> class GOTPLTPas
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
     switch (ref.kind()) {
+    case R_X86_64_32S:
+      static_cast<Derived *>(this)->handle32S(ref);
+      break;
     case R_X86_64_PLT32:
       static_cast<Derived *>(this)->handlePLT32(ref);
       break;
@@ -245,6 +248,10 @@ public:
       got->setOrdinal(ordinal++);
       mf.addAtom(*got);
     }
+    for (auto obj : _objectVector) {
+      obj->setOrdinal(ordinal++);
+      mf.addAtom(*obj);
+    }
   }
 
 protected:
@@ -257,9 +264,13 @@ protected:
   /// \brief Map Atoms to their PLT entries.
   llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
 
+  /// \brief Map Atoms to their Object entries.
+  llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
+
   /// \brief the list of GOT/PLT atoms
   std::vector<GOTAtom *> _gotVector;
   std::vector<PLTAtom *> _pltVector;
+  std::vector<ObjectAtom *> _objectVector;
 
   /// \brief GOT entry that is always 0. Used for undefined weaks.
   GOTAtom *_null;
@@ -300,6 +311,11 @@ public:
   }
 
   ErrorOr<void> handlePC32(const Reference &ref) { return handleIFUNC(ref); }
+
+  ErrorOr<void> handle32S(const Reference &ref) {
+    // Do nothing.
+    return error_code::success();
+  }
 };
 
 class DynamicGOTPLTPass LLVM_FINAL : public GOTPLTPass<DynamicGOTPLTPass> {
@@ -349,6 +365,29 @@ public:
     return pa;
   }
 
+  const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
+    auto obj = _objectMap.find(a);
+    if (obj != _objectMap.end())
+      return obj->second;
+
+    auto oa = new (_file._alloc) ObjectAtom(_file);
+    oa->addReference(R_X86_64_COPY, 0, a, 0);
+
+    oa->_name = a->name();
+    oa->_size = a->size();
+
+    _objectMap[a] = oa;
+    _objectVector.push_back(oa);
+    return oa;
+  }
+
+  ErrorOr<void> handle32S(const Reference &ref) {
+    if (auto sla = dyn_cast_or_null<SharedLibraryAtom>(ref.target()))
+      if (sla->type() == SharedLibraryAtom::Type::Data)
+        const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
+    return error_code::success();
+  }
+
   ErrorOr<void> handlePLT32(const Reference &ref) {
     // Turn this into a PC32 to the PLT entry.
     const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
@@ -363,8 +402,14 @@ public:
   }
 
   ErrorOr<void> handlePC32(const Reference &ref) {
-    if (ref.target() && isa<SharedLibraryAtom>(ref.target()))
-      return handlePLT32(ref);
+    if (!ref.target())
+      return error_code::success();
+    if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
+      if (sla->type() == SharedLibraryAtom::Type::Code)
+        return handlePLT32(ref);
+      else
+        return handleGOTPCREL(ref);
+    }
     return handleIFUNC(ref);
   }
 
@@ -384,7 +429,7 @@ public:
     return got->second;
   }
 
-  void handleGOTPCREL(const Reference &ref) {
+  ErrorOr<void> handleGOTPCREL(const Reference &ref) {
     const_cast<Reference &>(ref).setKind(R_X86_64_PC32);
     if (isa<UndefinedAtom>(ref.target()))
       const_cast<Reference &>(ref).setTarget(getNullGOT());
@@ -392,6 +437,7 @@ public:
       const_cast<Reference &>(ref).setTarget(getGOT(da));
     else if (const auto sla = dyn_cast<const SharedLibraryAtom>(ref.target()))
       const_cast<Reference &>(ref).setTarget(getSharedGOT(sla));
+    return error_code::success();
   }
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h?rev=191467&r1=191466&r2=191467&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h Thu Sep 26 17:09:16 2013
@@ -46,6 +46,7 @@ public:
     switch (r.kind()) {
     case llvm::ELF::R_X86_64_RELATIVE:
     case llvm::ELF::R_X86_64_GLOB_DAT:
+    case llvm::ELF::R_X86_64_COPY:
       return true;
     default:
       return false;

Added: lld/trunk/test/elf/Inputs/libundef.so
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/libundef.so?rev=191467&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/libundef.so (added) and lld/trunk/test/elf/Inputs/libundef.so Thu Sep 26 17:09:16 2013 differ

Added: lld/trunk/test/elf/Inputs/undef-from-main-so.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/undef-from-main-so.c?rev=191467&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/undef-from-main-so.c (added)
+++ lld/trunk/test/elf/Inputs/undef-from-main-so.c Thu Sep 26 17:09:16 2013
@@ -0,0 +1 @@
+int x[2] = {1, 2};

Added: lld/trunk/test/elf/Inputs/undef-from-main.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/undef-from-main.c?rev=191467&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/undef-from-main.c (added)
+++ lld/trunk/test/elf/Inputs/undef-from-main.c Thu Sep 26 17:09:16 2013
@@ -0,0 +1,5 @@
+extern int x[2];
+
+int main() {
+  x[0] = 2;
+}

Added: lld/trunk/test/elf/Inputs/undef.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/undef.o?rev=191467&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/undef.o (added) and lld/trunk/test/elf/Inputs/undef.o Thu Sep 26 17:09:16 2013 differ

Modified: lld/trunk/test/elf/dynamic.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/dynamic.test?rev=191467&r1=191466&r2=191467&view=diff
==============================================================================
--- lld/trunk/test/elf/dynamic.test (original)
+++ lld/trunk/test/elf/dynamic.test Thu Sep 26 17:09:16 2013
@@ -57,7 +57,7 @@ CHECK:          Name: i
 CHECK-NEXT:     Value: 0
 CHECK-NEXT:     Size:
 CHECK-NEXT:     Binding: Global
-CHECK-NEXT:     Type: Function
+CHECK-NEXT:     Type: Object
 CHECK:        }
 
 CHECK: DynamicSection [ (15 entries)

Copied: lld/trunk/test/elf/undef-from-main-dso.test (from r191466, lld/trunk/test/missing/undef-from-main-dso.test)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/undef-from-main-dso.test?p2=lld/trunk/test/elf/undef-from-main-dso.test&p1=lld/trunk/test/missing/undef-from-main-dso.test&r1=191466&r2=191467&rev=191467&view=diff
==============================================================================
--- lld/trunk/test/missing/undef-from-main-dso.test (original)
+++ lld/trunk/test/elf/undef-from-main-dso.test Thu Sep 26 17:09:16 2013
@@ -1,8 +1,6 @@
-RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -ltest %p/Inputs/undef-from-main.o
+RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef.o
 RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
 
-XFAIL: *
-
 # DSO source code:
 # int x[2] = { 1, 2 };
 #

Removed: lld/trunk/test/missing/undef-from-main-dso.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/missing/undef-from-main-dso.test?rev=191466&view=auto
==============================================================================
--- lld/trunk/test/missing/undef-from-main-dso.test (original)
+++ lld/trunk/test/missing/undef-from-main-dso.test (removed)
@@ -1,31 +0,0 @@
-RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -ltest %p/Inputs/undef-from-main.o
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
-
-XFAIL: *
-
-# DSO source code:
-# int x[2] = { 1, 2 };
-#
-# Main binary source code:
-#
-# extern int x[2];
-#
-# int main(void)
-# {
-#    x[0] = 2;
-# }
-#
-
-CHECK:       Relocations [
-CHECK-NEXT:    Section ({{[0-9]+}}) .rela.dyn {
-CHECK-NEXT:      0x{{[1-9A-F][0-9A-F]*}} R_X86_64_COPY x 0x0
-CHECK-NEXT:    }
-CHECK-NEXT:  ]
-
-CHECK:         Name: x ({{[0-9]+}}
-CHECK-NEXT:    Value: 0x{{[1-9A-F][0-9A-F]*}}
-CHECK-NEXT:    Size: 8
-CHECK-NEXT:    Binding: Global (0x1)
-CHECK-NEXT:    Type: Object (0x1)
-CHECK-NEXT:    Other: 0
-CHECK-NEXT:    Section: .bss





More information about the llvm-commits mailing list