[lld] r257814 - Add handleLoadedFile hook to the context.

Pete Cooper via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 14 13:53:14 PST 2016


Author: pete
Date: Thu Jan 14 15:53:13 2016
New Revision: 257814

URL: http://llvm.org/viewvc/llvm-project?rev=257814&view=rev
Log:
Add handleLoadedFile hook to the context.

This is called from the resolver on each file we decide we actually want to use.

Future commits will make use of this to extract useful information from the files and do
error checking against the context.  For example, ensure that files are the same arch as
each other.

Reviewed by Lang Hames.

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

Modified:
    lld/trunk/include/lld/Core/LinkingContext.h
    lld/trunk/include/lld/Core/Resolver.h
    lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
    lld/trunk/lib/Core/Resolver.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp

Modified: lld/trunk/include/lld/Core/LinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/LinkingContext.h?rev=257814&r1=257813&r2=257814&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/LinkingContext.h (original)
+++ lld/trunk/include/lld/Core/LinkingContext.h Thu Jan 14 15:53:13 2016
@@ -307,6 +307,15 @@ public:
   // Derived classes may use it to change the list of input files.
   virtual void finalizeInputFiles() {}
 
+  /// Callback invoked for each file the Resolver decides we are going to load.
+  /// This can be used to update context state based on the file, and emit
+  /// errors for any differences between the context state and a loaded file.
+  /// For example, we can error if we try to load a file which is a different
+  /// arch from that being linked.
+  virtual std::error_code handleLoadedFile(File &file) {
+    return std::error_code();
+  }
+
   TaskGroup &getTaskGroup() { return _taskGroup; }
 
   /// @}

Modified: lld/trunk/include/lld/Core/Resolver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Resolver.h?rev=257814&r1=257813&r2=257814&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/Resolver.h (original)
+++ lld/trunk/include/lld/Core/Resolver.h Thu Jan 14 15:53:13 2016
@@ -17,6 +17,7 @@
 #include "lld/Core/SymbolTable.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/Support/ErrorOr.h"
 #include <set>
 #include <unordered_map>
 #include <unordered_set>
@@ -43,13 +44,13 @@ public:
 
   // Handle files, this adds atoms from the current file thats
   // being processed by the resolver
-  bool handleFile(File &);
+  ErrorOr<bool> handleFile(File &);
 
   // Handle an archive library file.
-  bool handleArchiveFile(File &);
+  ErrorOr<bool> handleArchiveFile(File &);
 
   // Handle a shared library file.
-  void handleSharedLibrary(File &);
+  std::error_code handleSharedLibrary(File &);
 
   /// @brief do work of merging and resolving and return list
   bool resolve();
@@ -57,7 +58,7 @@ public:
   std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); }
 
 private:
-  typedef std::function<void(StringRef, bool)> UndefCallback;
+  typedef std::function<ErrorOr<bool>(StringRef, bool)> UndefCallback;
 
   bool undefinesAdded(int begin, int end);
   File *getFile(int &index);
@@ -73,7 +74,8 @@ private:
   bool checkUndefines();
   void removeCoalescedAwayAtoms();
   void checkDylibSymbolCollisions();
-  void forEachUndefines(File &file, bool searchForOverrides, UndefCallback callback);
+  ErrorOr<bool> forEachUndefines(File &file, bool searchForOverrides,
+                                 UndefCallback callback);
 
   void markLive(const Atom *atom);
   void addAtoms(const std::vector<const DefinedAtom *>&);

Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=257814&r1=257813&r2=257814&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Thu Jan 14 15:53:13 2016
@@ -342,6 +342,8 @@ public:
 
   void finalizeInputFiles() override;
 
+  std::error_code handleLoadedFile(File &file) override;
+
   bool customAtomOrderer(const DefinedAtom *left, const DefinedAtom *right,
                          bool &leftBeforeRight) const;
 

Modified: lld/trunk/lib/Core/Resolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=257814&r1=257813&r2=257814&view=diff
==============================================================================
--- lld/trunk/lib/Core/Resolver.cpp (original)
+++ lld/trunk/lib/Core/Resolver.cpp Thu Jan 14 15:53:13 2016
@@ -29,7 +29,9 @@
 
 namespace lld {
 
-bool Resolver::handleFile(File &file) {
+ErrorOr<bool> Resolver::handleFile(File &file) {
+  if (auto ec = _ctx.handleLoadedFile(file))
+    return ec;
   bool undefAdded = false;
   for (const DefinedAtom *atom : file.defined())
     doDefinedAtom(*atom);
@@ -46,9 +48,10 @@ bool Resolver::handleFile(File &file) {
   return undefAdded;
 }
 
-void Resolver::forEachUndefines(File &file, bool searchForOverrides,
-                                UndefCallback callback) {
+ErrorOr<bool> Resolver::forEachUndefines(File &file, bool searchForOverrides,
+                                         UndefCallback callback) {
   size_t i = _undefineIndex[&file];
+  bool undefAdded = false;
   do {
     for (; i < _undefines.size(); ++i) {
       StringRef undefName = _undefines[i];
@@ -60,7 +63,10 @@ void Resolver::forEachUndefines(File &fi
         _undefines[i] = "";
         continue;
       }
-      callback(undefName, false);
+      auto undefAddedOrError = callback(undefName, false);
+      if (undefAddedOrError.getError())
+        return undefAddedOrError;
+      undefAdded |= undefAddedOrError.get();
     }
     if (!searchForOverrides)
       continue;
@@ -69,43 +75,57 @@ void Resolver::forEachUndefines(File &fi
       // something that overrode this tentative, so always check.
       const Atom *curAtom = _symbolTable.findByName(tentDefName);
       assert(curAtom != nullptr);
-      if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom))
-        if (curDefAtom->merge() == DefinedAtom::mergeAsTentative)
-          callback(tentDefName, true);
+      if (const DefinedAtom *curDefAtom = dyn_cast<DefinedAtom>(curAtom)) {
+        if (curDefAtom->merge() == DefinedAtom::mergeAsTentative) {
+          auto undefAddedOrError = callback(tentDefName, true);
+          if (undefAddedOrError.getError())
+            return undefAddedOrError;
+          undefAdded |= undefAddedOrError.get();
+        }
+      }
     }
   } while (i < _undefines.size());
   _undefineIndex[&file] = i;
+  return undefAdded;
 }
 
-bool Resolver::handleArchiveFile(File &file) {
+ErrorOr<bool> Resolver::handleArchiveFile(File &file) {
   ArchiveLibraryFile *archiveFile = cast<ArchiveLibraryFile>(&file);
   bool searchForOverrides =
       _ctx.searchArchivesToOverrideTentativeDefinitions();
-  bool undefAdded = false;
-  forEachUndefines(file, searchForOverrides,
-                   [&](StringRef undefName, bool dataSymbolOnly) {
+  return forEachUndefines(file, searchForOverrides,
+                          [&](StringRef undefName,
+                              bool dataSymbolOnly)->ErrorOr<bool> {
     if (File *member = archiveFile->find(undefName, dataSymbolOnly)) {
       member->setOrdinal(_ctx.getNextOrdinalAndIncrement());
       member->beforeLink();
       updatePreloadArchiveMap();
-      undefAdded = handleFile(*member) || undefAdded;
+      return handleFile(*member);
     }
+    return false;
   });
-  return undefAdded;
 }
 
-void Resolver::handleSharedLibrary(File &file) {
+std::error_code Resolver::handleSharedLibrary(File &file) {
   // Add all the atoms from the shared library
   SharedLibraryFile *sharedLibrary = cast<SharedLibraryFile>(&file);
-  handleFile(*sharedLibrary);
+  auto undefAddedOrError = handleFile(*sharedLibrary);
+  if (undefAddedOrError.getError())
+    return undefAddedOrError.getError();
   bool searchForOverrides =
       _ctx.searchSharedLibrariesToOverrideTentativeDefinitions();
-  forEachUndefines(file, searchForOverrides,
-                   [&](StringRef undefName, bool dataSymbolOnly) {
+  undefAddedOrError = forEachUndefines(file, searchForOverrides,
+                                       [&](StringRef undefName,
+                                           bool dataSymbolOnly)->ErrorOr<bool> {
     if (const SharedLibraryAtom *atom =
             sharedLibrary->exports(undefName, dataSymbolOnly))
       doSharedLibraryAtom(*atom);
+    return false;
   });
+
+  if (undefAddedOrError.getError())
+    return undefAddedOrError.getError();
+  return std::error_code();
 }
 
 bool Resolver::doUndefinedAtom(const UndefinedAtom &atom) {
@@ -318,7 +338,7 @@ bool Resolver::resolveUndefines() {
     file->beforeLink();
     updatePreloadArchiveMap();
     switch (file->kind()) {
-    case File::kindObject:
+    case File::kindObject: {
       // The same file may be visited more than once if the file is
       // in --start-group and --end-group. Only library files should
       // be processed more than once.
@@ -327,17 +347,35 @@ bool Resolver::resolveUndefines() {
       seen.insert(file);
       assert(!file->hasOrdinal());
       file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
-      undefAdded = handleFile(*file);
+      auto undefAddedOrError = handleFile(*file);
+      if (undefAddedOrError.getError()) {
+        llvm::errs() << "Error in " + file->path()
+                     << ": " << undefAddedOrError.getError().message() << "\n";
+        return false;
+      }
+      undefAdded = undefAddedOrError.get();
       break;
-    case File::kindArchiveLibrary:
+    }
+    case File::kindArchiveLibrary: {
       if (!file->hasOrdinal())
         file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
-      undefAdded = handleArchiveFile(*file);
+      auto undefAddedOrError = handleArchiveFile(*file);
+      if (undefAddedOrError.getError()) {
+        llvm::errs() << "Error in " + file->path()
+                     << ": " << undefAddedOrError.getError().message() << "\n";
+        return false;
+      }
+      undefAdded = undefAddedOrError.get();
       break;
+    }
     case File::kindSharedLibrary:
       if (!file->hasOrdinal())
         file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
-      handleSharedLibrary(*file);
+      if (auto EC = handleSharedLibrary(*file)) {
+        llvm::errs() << "Error in " + file->path()
+                     << ": " << EC.message() << "\n";
+        return false;
+      }
       break;
     }
     _newUndefinesAdded[file] = undefAdded;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=257814&r1=257813&r2=257814&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Thu Jan 14 15:53:13 2016
@@ -990,4 +990,8 @@ void MachOLinkingContext::finalizeInputF
   elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
 }
 
+std::error_code MachOLinkingContext::handleLoadedFile(File &file) {
+  return std::error_code();
+}
+
 } // end namespace lld




More information about the llvm-commits mailing list