[PATCH] [lld][ELF] Add explictly exported atoms and export R_*_COPY'ed atoms.

Michael Spencer bigcheesegs at gmail.com
Tue Oct 1 12:06:16 PDT 2013


Hi kledzik, shankarke, joerg,

This adds explicitly exported atoms to ELFLinkingContext and uses them to export copied objects properly. With this patch std::cout works (it crashes after, but I have a fix for that).

The problem with this approach is the const_cast on the context. There are a few fixes for this.

* Make LinkingContext non const.
* Make _explicitlyExportedAtoms a pointer to non-const.
* Make explicit exporting an attribute of the Atom.

Personally I like adding it to DefinedAtom.

We also have another problem. In the test we add two checks for x. This is because we have no way to replace the SharedLibraryAtom x with the ObjectAtom x.

http://llvm-reviews.chandlerc.com/D1799

Files:
  include/lld/ReaderWriter/ELFLinkingContext.h
  lib/ReaderWriter/ELF/OutputELFWriter.h
  lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
  test/elf/undef-from-main-dso.test

Index: include/lld/ReaderWriter/ELFLinkingContext.h
===================================================================
--- include/lld/ReaderWriter/ELFLinkingContext.h
+++ include/lld/ReaderWriter/ELFLinkingContext.h
@@ -23,6 +23,7 @@
 #include "llvm/Support/ELF.h"
 
 #include <memory>
+#include <unordered_set>
 
 namespace lld {
 class DefinedAtom;
@@ -206,6 +207,15 @@
     return _rpathLinkList;
   }
 
+  void addExplicitlyExportedAtom(const DefinedAtom *a) {
+    _explicitlyExportedAtoms.insert(a);
+  }
+
+  const std::unordered_set<const DefinedAtom *> &
+  getExplicitlyExportedAtoms() const {
+    return _explicitlyExportedAtoms;
+  }
+
 private:
   ELFLinkingContext() LLVM_DELETED_FUNCTION;
 
@@ -241,6 +251,10 @@
   StringRef _soname;
   StringRefVector _rpathList;
   StringRefVector _rpathLinkList;
+
+  /// \brief The set of explicitly exported atoms which should be added to the
+  ///   dynamic symbol table.
+  std::unordered_set<const DefinedAtom *> _explicitlyExportedAtoms;
 };
 } // end namespace lld
 
Index: lib/ReaderWriter/ELF/OutputELFWriter.h
===================================================================
--- lib/ReaderWriter/ELF/OutputELFWriter.h
+++ lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -154,6 +154,14 @@
     _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
     _soNeeded.insert(sla->loadName());
   }
+  for (auto sec : this->_layout->sections())
+    if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
+      for (const auto &atom : section->atoms()) {
+        const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
+        if (da && _context.getExplicitlyExportedAtoms().count(da))
+          this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+                                               atom->_virtualAddr, atom);
+      }
   for (const auto &loadName : _soNeeded) {
     Elf_Dyn dyn;
     dyn.d_tag = DT_NEEDED;
Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
===================================================================
--- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
+++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.cpp
@@ -206,7 +206,7 @@
 
 public:
   GOTPLTPass(const ELFLinkingContext &ctx)
-      : _file(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
+      : _file(ctx), _ctx(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr),
         _got1(nullptr) {}
 
   /// \brief Do the pass.
@@ -257,6 +257,7 @@
 protected:
   /// \brief Owner of all the Atoms created by this pass.
   ELFPassFile _file;
+  const ELFLinkingContext &_ctx;
 
   /// \brief Map Atoms to their GOT entries.
   llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
@@ -371,13 +372,14 @@
       return obj->second;
 
     auto oa = new (_file._alloc) ObjectAtom(_file);
-    oa->addReference(R_X86_64_COPY, 0, a, 0);
+    oa->addReference(R_X86_64_COPY, 0, oa, 0);
 
     oa->_name = a->name();
     oa->_size = a->size();
 
     _objectMap[a] = oa;
     _objectVector.push_back(oa);
+    const_cast<ELFLinkingContext &>(_ctx).addExplicitlyExportedAtom(oa);
     return oa;
   }
 
Index: test/elf/undef-from-main-dso.test
===================================================================
--- test/elf/undef-from-main-dso.test
+++ test/elf/undef-from-main-dso.test
@@ -1,8 +1,8 @@
 RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef.o
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
+RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
 
 RUN: lld -flavor gnu -e main -o %t -L%p/Inputs -lundef %p/Inputs/undef-pc32.o
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
+RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
 
 # DSO source code:
 # int x[2] = { 1, 2 };
@@ -30,3 +30,13 @@
 CHECK-NEXT:    Type: Object (0x1)
 CHECK-NEXT:    Other: 0
 CHECK-NEXT:    Section: .bss
+
+CHECK:         Name: x@ ({{[0-9]+}}
+
+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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1799.1.patch
Type: text/x-patch
Size: 4141 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131001/5738e42b/attachment.bin>


More information about the llvm-commits mailing list