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

Michael Spencer bigcheesegs at gmail.com
Tue Nov 5 16:19:30 PST 2013


  Add DynamicExport to DefinedAtom.

Hi kledzik, shankarke, joerg,

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

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D1799?vs=4583&id=5361#toc

Files:
  include/lld/Core/DefinedAtom.h
  lib/ReaderWriter/ELF/Atoms.h
  lib/ReaderWriter/ELF/OutputELFWriter.h
  lib/ReaderWriter/Native/NativeFileFormat.h
  lib/ReaderWriter/Native/ReaderNative.cpp
  lib/ReaderWriter/Native/WriterNative.cpp
  lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
  test/elf/undef-from-main-dso.test

Index: include/lld/Core/DefinedAtom.h
===================================================================
--- include/lld/Core/DefinedAtom.h
+++ include/lld/Core/DefinedAtom.h
@@ -185,6 +185,14 @@
     deadStripAlways         // linker must remove this atom if unused
   };
 
+  enum DynamicExport {
+    /// \brief The linker may or may not export this atom dynamicly depending on
+    ///   the output type and other context of the link.
+    dynamicExportNormal,
+    /// \brief The linker will always export this atom dynamicly.
+    dynamicExportAlways,
+  };
+
   struct Alignment {
     Alignment(int p2, int m = 0)
       : powerOf2(p2)
@@ -252,6 +260,11 @@
   /// \brief constraints on whether the linker may dead strip away this atom.
   virtual DeadStripKind deadStrip() const = 0;
 
+  /// \brief Under which conditions should this atom be dynamicly exported.
+  virtual DynamicExport dynamicExport() const {
+    return dynamicExportNormal;
+  }
+
   /// \brief Returns the OS memory protections required for this atom's content
   /// at runtime.
   ///
Index: lib/ReaderWriter/ELF/Atoms.h
===================================================================
--- lib/ReaderWriter/ELF/Atoms.h
+++ lib/ReaderWriter/ELF/Atoms.h
@@ -809,6 +809,8 @@
 
   virtual uint64_t size() const { return _size; }
 
+  virtual DynamicExport dynamicExport() const { return dynamicExportAlways; }
+
   virtual ContentPermissions permissions() const { return permRW_; }
 
   virtual ArrayRef<uint8_t> rawContent() const {
Index: lib/ReaderWriter/ELF/OutputELFWriter.h
===================================================================
--- lib/ReaderWriter/ELF/OutputELFWriter.h
+++ lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -151,6 +151,14 @@
 template <class ELFT>
 void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
   ScopedTask task(getDefaultDomain(), "buildDynamicSymbolTable");
+  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 && da->dynamicExport() == DefinedAtom::dynamicExportAlways)
+          _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
+                                         atom->_virtualAddr, atom);
+      }
   for (const auto sla : file.sharedLibrary()) {
     _dynamicSymbolTable->addSymbol(sla, ELF::SHN_UNDEF);
     _soNeeded.insert(sla->loadName());
Index: lib/ReaderWriter/Native/NativeFileFormat.h
===================================================================
--- lib/ReaderWriter/Native/NativeFileFormat.h
+++ lib/ReaderWriter/Native/NativeFileFormat.h
@@ -152,6 +152,7 @@
   uint8_t   contentType;
   uint8_t   sectionChoiceAndPosition; // high nibble is choice, low is position
   uint8_t   deadStrip;
+  uint8_t   dynamicExport;
   uint8_t   permissions;
   uint8_t   alias;
 };
Index: lib/ReaderWriter/Native/ReaderNative.cpp
===================================================================
--- lib/ReaderWriter/Native/ReaderNative.cpp
+++ lib/ReaderWriter/Native/ReaderNative.cpp
@@ -91,6 +91,10 @@
      return (DefinedAtom::DeadStripKind)(attributes().deadStrip);
   }
 
+  virtual DynamicExport dynamicExport() const {
+    return (DynamicExport)attributes().dynamicExport;
+  }
+
   virtual DefinedAtom::ContentPermissions permissions() const {
      return (DefinedAtom::ContentPermissions)(attributes().permissions);
   }
Index: lib/ReaderWriter/Native/WriterNative.cpp
===================================================================
--- lib/ReaderWriter/Native/WriterNative.cpp
+++ lib/ReaderWriter/Native/WriterNative.cpp
@@ -444,6 +444,7 @@
     attrs.sectionChoiceAndPosition
                           = atom.sectionChoice() << 4 | atom.sectionPosition();
     attrs.deadStrip         = atom.deadStrip();
+    attrs.dynamicExport     = atom.dynamicExport();
     attrs.permissions       = atom.permissions();
     attrs.alias             = atom.isAlias();
   }
Index: lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
===================================================================
--- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -384,6 +384,13 @@
   }
 };
 
+template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DynamicExport> {
+  static void enumeration(IO &io, lld::DefinedAtom::DynamicExport &value) {
+    io.enumCase(value, "normal", lld::DefinedAtom::dynamicExportNormal);
+    io.enumCase(value, "always", lld::DefinedAtom::dynamicExportAlways);
+  }
+};
+
 template <>
 struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> {
   static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) {
@@ -812,8 +819,9 @@
           _merge(atom->merge()), _contentType(atom->contentType()),
           _alignment(atom->alignment()), _sectionChoice(atom->sectionChoice()),
           _sectionPosition(atom->sectionPosition()),
-          _deadStrip(atom->deadStrip()), _permissions(atom->permissions()),
-          _size(atom->size()), _sectionName(atom->customSectionName()) {
+          _deadStrip(atom->deadStrip()), _dynamicExport(atom->dynamicExport()),
+          _permissions(atom->permissions()), _size(atom->size()),
+          _sectionName(atom->customSectionName()) {
       for (const lld::Reference *r : *atom)
         _references.push_back(r);
       if (!atom->occupiesDiskSpace())
@@ -862,6 +870,7 @@
     virtual StringRef customSectionName() const { return _sectionName; }
     virtual SectionPosition sectionPosition() const { return _sectionPosition; }
     virtual DeadStripKind deadStrip() const { return _deadStrip; }
+    virtual DynamicExport dynamicExport() const { return _dynamicExport; }
     virtual ContentPermissions permissions() const { return _permissions; }
     virtual bool isAlias() const { return false; }
     ArrayRef<uint8_t> rawContent() const {
@@ -905,6 +914,7 @@
     SectionChoice _sectionChoice;
     SectionPosition _sectionPosition;
     DeadStripKind _deadStrip;
+    DynamicExport _dynamicExport;
     ContentPermissions _permissions;
     uint32_t _ordinal;
     std::vector<ImplicitHex8> _content;
@@ -949,6 +959,8 @@
                    lld::DefinedAtom::sectionPositionAny);
     io.mapOptional("dead-strip", keys->_deadStrip,
                    lld::DefinedAtom::deadStripNormal);
+    io.mapOptional("dynamic-export", keys->_dynamicExport,
+                   lld::DefinedAtom::dynamicExportNormal);
     // default permissions based on content type
     io.mapOptional("permissions", keys->_permissions,
                    lld::DefinedAtom::permissions(keys->_contentType));
Index: test/elf/undef-from-main-dso.test
===================================================================
--- test/elf/undef-from-main-dso.test
+++ test/elf/undef-from-main-dso.test
@@ -1,10 +1,10 @@
 RUN: lld -flavor gnu -target x86_64 -e main -o %t -L%p/Inputs \
 RUN:   %p/Inputs/undef.o -lundef
-RUN: llvm-readobj -relocations -symbols %t | FileCheck %s
+RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
 
 RUN: lld -flavor gnu -target x86_64 -e main -o %t -L%p/Inputs \
 RUN:   %p/Inputs/undef-pc32.o -lundef
-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 };
@@ -21,7 +21,7 @@
 
 CHECK:       Relocations [
 CHECK-NEXT:    Section ({{[0-9]+}}) .rela.dyn {
-CHECK-NEXT:      0x{{[1-9A-F][0-9A-F]*}} R_X86_64_COPY - 0x0
+CHECK-NEXT:      0x{{[1-9A-F][0-9A-F]*}} R_X86_64_COPY x 0x0
 CHECK-NEXT:    }
 CHECK-NEXT:  ]
 
@@ -32,3 +32,13 @@
 CHECK-NEXT:    Type: Object (0x1)
 CHECK-NEXT:    Other: 0
 CHECK-NEXT:    Section: .bss
+
+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
+
+CHECK:         Name: x@ ({{[0-9]+}}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1799.2.patch
Type: text/x-patch
Size: 8069 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131105/f24330d2/attachment.bin>


More information about the llvm-commits mailing list