Move alias symbols from ELFLinkingContext to LinkingContext.
authorRui Ueyama <ruiu@google.com>
Thu, 22 May 2014 21:37:56 +0000 (21:37 +0000)
committerRui Ueyama <ruiu@google.com>
Thu, 22 May 2014 21:37:56 +0000 (21:37 +0000)
Alias symbols are SimpleDefinedAtoms and are platform neutral. They
don't have to belong ELF. This patch is to make it available to all
platforms. No functionality change intended.

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

llvm-svn: 209475

lld/include/lld/Core/LinkingContext.h
lld/include/lld/ReaderWriter/Alias.h [new file with mode: 0644]
lld/include/lld/ReaderWriter/ELFLinkingContext.h
lld/lib/Core/LinkingContext.cpp
lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp

index 0c6e201..78e4e37 100644 (file)
@@ -214,6 +214,11 @@ public:
 
   void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
 
+  void addAlias(StringRef from, StringRef to) { _aliasSymbols[from] = to; }
+  const std::map<std::string, std::string> &getAliases() const {
+    return _aliasSymbols;
+  }
+
   void setInputGraph(std::unique_ptr<InputGraph> inputGraph) {
     _inputGraph = std::move(inputGraph);
   }
@@ -307,14 +312,17 @@ protected:
   /// Abstract method to lazily instantiate the Writer.
   virtual Writer &writer() const = 0;
 
-  /// Method to create a internal file for the entry symbol
+  /// Method to create an internal file for the entry symbol
   virtual std::unique_ptr<File> createEntrySymbolFile() const;
   std::unique_ptr<File> createEntrySymbolFile(StringRef filename) const;
 
-  /// Method to create a internal file for an undefined symbol
+  /// Method to create an internal file for an undefined symbol
   virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
   std::unique_ptr<File> createUndefinedSymbolFile(StringRef filename) const;
 
+  /// Method to create an internal file for alias symbols
+  std::unique_ptr<File> createAliasSymbolFile() const;
+
   StringRef _outputPath;
   StringRef _entrySymbolName;
   bool _deadStrip;
@@ -330,6 +338,7 @@ protected:
   bool _allowShlibUndefines;
   OutputFileType _outputFileType;
   std::vector<StringRef> _deadStripRoots;
+  std::map<std::string, std::string> _aliasSymbols;
   std::vector<const char *> _llvmOptions;
   StringRefVector _initialUndefinedSymbols;
   std::unique_ptr<InputGraph> _inputGraph;
diff --git a/lld/include/lld/ReaderWriter/Alias.h b/lld/include/lld/ReaderWriter/Alias.h
new file mode 100644 (file)
index 0000000..d7d44f2
--- /dev/null
@@ -0,0 +1,91 @@
+//===- lld/ReaderWriter/Alias.h - Alias atoms -----------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provide alias atoms.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ALIAS_H
+#define LLD_READER_WRITER_ALIAS_H
+
+#include "lld/Core/LLVM.h"
+#include "lld/ReaderWriter/Simple.h"
+
+#include <string>
+
+namespace lld {
+
+// An AliasAtom is a zero-size atom representing an alias for other atom. It has
+// a LayoutAfter reference to the target atom, so that this atom and the target
+// atom will be laid out at the same location in the final result. Initially
+// the target atom is an undefined atom. Resolver will replace it with a defined
+// one.
+//
+// It does not have attributes itself. Most member function calls are forwarded
+// to the target atom.
+class AliasAtom : public SimpleDefinedAtom {
+public:
+  AliasAtom(const File &file, StringRef name)
+      : SimpleDefinedAtom(file), _target(nullptr), _name(name) {}
+
+  StringRef name() const override { return _name; }
+  uint64_t size() const override { return 0; }
+  ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
+
+  Scope scope() const override {
+    getTarget();
+    return _target ? _target->scope() : scopeLinkageUnit;
+  }
+
+  Merge merge() const override {
+    getTarget();
+    return _target ? _target->merge() : mergeNo;
+  }
+
+  ContentType contentType() const override {
+    getTarget();
+    return _target ? _target->contentType() : typeUnknown;
+  }
+
+  Interposable interposable() const override {
+    getTarget();
+    return _target ? _target->interposable() : interposeNo;
+  }
+
+  SectionChoice sectionChoice() const override {
+    getTarget();
+    return _target ? _target->sectionChoice() : sectionBasedOnContent;
+  }
+
+  StringRef customSectionName() const override {
+    getTarget();
+    return _target ? _target->customSectionName() : StringRef("");
+  }
+
+private:
+  void getTarget() const {
+    if (_target)
+      return;
+    for (const Reference *r : *this) {
+      if (r->kindNamespace() == lld::Reference::KindNamespace::all &&
+          r->kindValue() == lld::Reference::kindLayoutAfter) {
+        _target = dyn_cast<DefinedAtom>(r->target());
+        return;
+      }
+    }
+  }
+
+  mutable const DefinedAtom *_target;
+  std::string _name;
+};
+
+} // end namespace lld
+
+#endif
index 4708d16..f551a3c 100644 (file)
@@ -194,10 +194,6 @@ public:
     _absoluteSymbols[name] = addr;
   }
 
-  void addAlias(StringRef sym, StringRef target) {
-    _aliasSymbols[sym] = target;
-  }
-
   /// Return the list of initializer symbols that are specified in the
   /// linker command line, using the -init option.
   range<const StringRef *> initFunctions() const {
@@ -241,10 +237,6 @@ public:
     return _absoluteSymbols;
   }
 
-  const std::map<std::string, std::string> &getAliases() const {
-    return _aliasSymbols;
-  }
-
   /// \brief Helper function to allocate strings.
   StringRef allocateString(StringRef ref) const {
     char *x = _allocator.Allocate<char>(ref.size() + 1);
@@ -292,7 +284,6 @@ protected:
   StringRefVector _rpathList;
   StringRefVector _rpathLinkList;
   std::map<std::string, uint64_t> _absoluteSymbols;
-  std::map<std::string, std::string> _aliasSymbols;
 };
 } // end namespace lld
 
index 675de3e..56388e1 100644 (file)
@@ -9,9 +9,9 @@
 
 #include "lld/Core/LinkingContext.h"
 #include "lld/Core/Resolver.h"
-#include "lld/ReaderWriter/Writer.h"
+#include "lld/ReaderWriter/Alias.h"
 #include "lld/ReaderWriter/Simple.h"
-
+#include "lld/ReaderWriter/Writer.h"
 #include "llvm/ADT/Triple.h"
 
 namespace lld {
@@ -71,12 +71,32 @@ LinkingContext::createUndefinedSymbolFile(StringRef filename) const {
   return std::move(undefinedSymFile);
 }
 
+std::unique_ptr<File> LinkingContext::createAliasSymbolFile() const {
+  if (getAliases().empty())
+    return nullptr;
+  std::unique_ptr<SimpleFile> file(new SimpleFile("<alias>"));
+  for (const auto &i : getAliases()) {
+    StringRef from = i.first;
+    StringRef to = i.second;
+    SimpleDefinedAtom *fromAtom = new (_allocator) AliasAtom(*file, from);
+    UndefinedAtom *toAtom = new (_allocator) SimpleUndefinedAtom(*file, to);
+    fromAtom->addReference(Reference::KindNamespace::all,
+                           Reference::KindArch::all, Reference::kindLayoutAfter,
+                           0, toAtom, 0);
+    file->addAtom(*fromAtom);
+    file->addAtom(*toAtom);
+  }
+  return std::move(file);
+}
+
 void LinkingContext::createInternalFiles(
     std::vector<std::unique_ptr<File> > &result) const {
   if (std::unique_ptr<File> file = createEntrySymbolFile())
     result.push_back(std::move(file));
   if (std::unique_ptr<File> file = createUndefinedSymbolFile())
     result.push_back(std::move(file));
+  if (std::unique_ptr<File> file = createAliasSymbolFile())
+    result.push_back(std::move(file));
 }
 
 void LinkingContext::addPasses(PassManager &pm) {}
index 430de66..89f5022 100644 (file)
@@ -41,70 +41,6 @@ private:
   uint64_t _value;
 };
 
-// An AliasAtom is a zero-size atom representing an alias for other atom. It has
-// a LayoutAfter reference to the target atom, so that this atom and the target
-// atom will be laid out at the same location in the final result. Initially
-// the target atom is an undefined atom. Resolver will replace it with a defined
-// one.
-//
-// It does not have attributes itself. Most member function calls are forwarded
-// to the target atom.
-class AliasAtom : public SimpleDefinedAtom {
-public:
-  AliasAtom(const File &file, StringRef name)
-      : SimpleDefinedAtom(file), _target(nullptr), _name(name) {}
-
-  StringRef name() const override { return _name; }
-  uint64_t size() const override { return 0; }
-  ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
-
-  Scope scope() const override {
-    getTarget();
-    return _target ? _target->scope() : scopeLinkageUnit;
-  }
-
-  Merge merge() const override {
-    getTarget();
-    return _target ? _target->merge() : mergeNo;
-  }
-
-  ContentType contentType() const override {
-    getTarget();
-    return _target ? _target->contentType() : typeUnknown;
-  }
-
-  Interposable interposable() const override {
-    getTarget();
-    return _target ? _target->interposable() : interposeNo;
-  }
-
-  SectionChoice sectionChoice() const override {
-    getTarget();
-    return _target ? _target->sectionChoice() : sectionBasedOnContent;
-  }
-
-  StringRef customSectionName() const override {
-    getTarget();
-    return _target ? _target->customSectionName() : StringRef("");
-  }
-
-private:
-  void getTarget() const {
-    if (_target)
-      return;
-    for (const Reference *r : *this) {
-      if (r->kindNamespace() == lld::Reference::KindNamespace::all &&
-          r->kindValue() == lld::Reference::kindLayoutAfter) {
-        _target = dyn_cast<DefinedAtom>(r->target());
-        return;
-      }
-    }
-  }
-
-  mutable const DefinedAtom *_target;
-  StringRef _name;
-};
-
 class CommandLineUndefinedAtom : public SimpleUndefinedAtom {
 public:
   CommandLineUndefinedAtom(const File &f, StringRef name)
@@ -279,17 +215,6 @@ void ELFLinkingContext::createInternalFiles(
     uint64_t val = i.second;
     file->addAtom(*(new (_allocator) CommandLineAbsoluteAtom(*file, sym, val)));
   }
-  for (auto &i : getAliases()) {
-    StringRef from = i.first;
-    StringRef to = i.second;
-    SimpleDefinedAtom *fromAtom = new (_allocator) AliasAtom(*file, from);
-    UndefinedAtom *toAtom = new (_allocator) SimpleUndefinedAtom(*file, to);
-    fromAtom->addReference(Reference::KindNamespace::all,
-                           Reference::KindArch::all, Reference::kindLayoutAfter,
-                           0, toAtom, 0);
-    file->addAtom(*fromAtom);
-    file->addAtom(*toAtom);
-  }
   files.push_back(std::move(file));
   LinkingContext::createInternalFiles(files);
 }