Don't open the file again in the gold plugin. To be able to do this, update
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 8 Feb 2011 22:40:47 +0000 (22:40 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 8 Feb 2011 22:40:47 +0000 (22:40 +0000)
MemoryBuffer::getOpenFile to not close the file descriptor.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125128 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm-c/lto.h
include/llvm/Support/MemoryBuffer.h
lib/Support/MemoryBuffer.cpp
tools/gold/gold-plugin.cpp
tools/lto/LTOModule.cpp
tools/lto/LTOModule.h
tools/lto/lto.cpp
tools/lto/lto.exports

index 08c12af40aeeac801fb9e444365c67fed381822e..1c42ce0cec7765845b3843976da64891e5b76a1c 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <unistd.h>
 
 #define LTO_API_VERSION 4
 
@@ -121,6 +122,13 @@ lto_module_create(const char* path);
 extern lto_module_t
 lto_module_create_from_memory(const void* mem, size_t length);
 
+/**
+ * Loads an object file from disk. The seek point of fd is not preserved.
+ * Returns NULL on error (check lto_get_error_message() for details).
+ */
+extern lto_module_t
+lto_module_create_from_fd(int fd, const char *path, off_t size);
+
 
 /**
  * Frees all memory internally allocated by the module.
index fa1942341b9b0ccc92f284d3d8f297166f67853e..b6243b7b10dde2d4fda5a979010f0b22827bd599 100644 (file)
@@ -69,8 +69,7 @@ public:
                             int64_t FileSize = -1);
 
   /// getOpenFile - Given an already-open file descriptor, read the file and
-  /// return a MemoryBuffer.  This takes ownership of the descriptor,
-  /// immediately closing it after reading the file.
+  /// return a MemoryBuffer.
   static error_code getOpenFile(int FD, const char *Filename,
                                 OwningPtr<MemoryBuffer> &result,
                                 int64_t FileSize = -1);
index b7d70dd603d17355a768a61bd6b63c8f1d694ad4..a0c650d6820b0ed859a5f7f9c62b45f717dd8f8d 100644 (file)
@@ -179,14 +179,6 @@ public:
     sys::Path::UnMapFilePages(getBufferStart(), getBufferSize());
   }
 };
-
-/// FileCloser - RAII object to make sure an FD gets closed properly.
-class FileCloser {
-  int FD;
-public:
-  explicit FileCloser(int FD) : FD(FD) {}
-  ~FileCloser() { ::close(FD); }
-};
 }
 
 error_code MemoryBuffer::getFile(StringRef Filename,
@@ -208,15 +200,14 @@ error_code MemoryBuffer::getFile(const char *Filename,
   if (FD == -1) {
     return error_code(errno, posix_category());
   }
-
-  return getOpenFile(FD, Filename, result, FileSize);
+  error_code ret = getOpenFile(FD, Filename, result, FileSize);
+  close(FD);
+  return ret;
 }
 
 error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
                                      OwningPtr<MemoryBuffer> &result,
                                      int64_t FileSize) {
-  FileCloser FC(FD); // Close FD on return.
-
   // If we don't know the file size, use fstat to find out.  fstat on an open
   // file descriptor is cheaper than stat on a random path.
   if (FileSize == -1) {
index 1639ac1dc449fd3cc706d2d6d9a46af8612017fc..257c766345dd46a46a425da2cdd80f4a522c9bdc 100644 (file)
@@ -241,7 +241,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
 /// with add_symbol if possible.
 static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
                                         int *claimed) {
-  void *buf = NULL;
+  lto_module_t M;
+
   if (file->offset) {
     // Gold has found what might be IR part-way inside of a file, such as
     // an .a archive.
@@ -252,7 +253,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
                  file->offset, sys::StrError(errno).c_str());
       return LDPS_ERR;
     }
-    buf = malloc(file->filesize);
+    void *buf = malloc(file->filesize);
     if (!buf) {
       (*message)(LDPL_ERROR,
                  "Failed to allocate buffer for archive member of size: %d\n",
@@ -272,16 +273,31 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
       free(buf);
       return LDPS_OK;
     }
-  } else if (!lto_module_is_object_file(file->name))
-    return LDPS_OK;
+    M = lto_module_create_from_memory(buf, file->filesize);
+    free(buf);
+  } else {
+    // FIXME: We should not need to pass -1 as the file size, but there
+    // is a bug in BFD that causes it to pass 0 to us. Remove this once
+    // that is fixed.
+    off_t size = file->filesize ? file->filesize : -1;
+
+    // FIXME: We should not need to reset the position in the file, but there
+    // is a bug in BFD. Remove this once that is fixed.
+    off_t old_pos = lseek(file->fd, 0, SEEK_CUR);
+
+    lseek(file->fd, 0, SEEK_SET);
+    M = lto_module_create_from_fd(file->fd, file->name, size);
+
+    lseek(file->fd, old_pos, SEEK_SET);
+    if (!M)
+      return LDPS_OK;
+  }
 
   *claimed = 1;
   Modules.resize(Modules.size() + 1);
   claimed_file &cf = Modules.back();
+  cf.M = M;
 
-  cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) :
-               lto_module_create(file->name);
-  free(buf);
   if (!cf.M) {
     (*message)(LDPL_ERROR, "Failed to create LLVM module: %s",
                lto_get_error_message());
index e2ecabcc1c367c9440d9d737b387362e4e127496..ca937bf2ff080d986519d0a2cfc30d23d0c1de4c 100644 (file)
@@ -87,6 +87,17 @@ LTOModule *LTOModule::makeLTOModule(const char *path,
   return makeLTOModule(buffer.get(), errMsg);
 }
 
+LTOModule *LTOModule::makeLTOModule(int fd, const char *path,
+                                    off_t size,
+                                    std::string &errMsg) {
+  OwningPtr<MemoryBuffer> buffer;
+  if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, size)) {
+    errMsg = ec.message();
+    return NULL;
+  }
+  return makeLTOModule(buffer.get(), errMsg);
+}
+
 /// makeBuffer - Create a MemoryBuffer from a memory range.  MemoryBuffer
 /// requires the byte past end of the buffer to be a zero.  We might get lucky
 /// and already be that way, otherwise make a copy.  Also if next byte is on a
index a19acc0d7378ec30995a6c50c56f5a547a8d8d5c..1794d81c0a9c573058c46a3f1a1e02f593933616 100644 (file)
@@ -51,6 +51,9 @@ struct LTOModule {
 
     static LTOModule*        makeLTOModule(const char* path,
                                           std::string& errMsg);
+    static LTOModule*        makeLTOModule(int fd, const char *path,
+                                           off_t size,
+                                           std::string& errMsg);
     static LTOModule*        makeLTOModule(const void* mem, size_t length,
                                            std::string& errMsg);
 
index 75b40f428761ea6968a399698041664d51821e96..7d4871d9253dbe8fd57344159bf6e88ae3f80b8b 100644 (file)
@@ -91,6 +91,14 @@ lto_module_t lto_module_create(const char* path)
      return LTOModule::makeLTOModule(path, sLastErrorString);
 }
 
+//
+// loads an object file from disk
+// returns NULL on error (check lto_get_error_message() for details)
+//
+lto_module_t lto_module_create_from_fd(int fd, const char *path, off_t size)
+{
+     return LTOModule::makeLTOModule(fd, path, size, sLastErrorString);
+}
 
 //
 // loads an object file from memory 
index 4dbf760d3882a71892e925e733557aec683f006f..a3740911edc1967bc04ffd4ee43501505c4b72b6 100644 (file)
@@ -1,6 +1,7 @@
 lto_get_error_message
 lto_get_version
 lto_module_create
+lto_module_create_from_fd
 lto_module_create_from_memory
 lto_module_get_num_symbols
 lto_module_get_symbol_attribute