All cases are covered, no need for a default. This deals with the
[oota-llvm.git] / tools / gold / gold-plugin.cpp
index a42ce4f3e8d98187e08d3788b646ae05d5f32865..9c17da6a4cb6e4a83e0f0c3cc633523b9c114aa5 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Config/config.h"
+#include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H
 #include "plugin-api.h"
 
 #include "llvm-c/lto.h"
 
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/Errno.h"
 #include "llvm/Support/Path.h"
@@ -150,6 +153,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
         switch (tv->tv_u.tv_val) {
           case LDPO_REL:  // .o
           case LDPO_DYN:  // .so
+          // FIXME: Replace 3 with LDPO_PIE once that is in a released binutils.
+          case 3: // position independent executable
             output_type = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
             break;
           case LDPO_EXEC:  // .exe
@@ -235,25 +240,38 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
 static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
                                         int *claimed) {
   lto_module_t M;
-
+  const void *view;
+  OwningPtr<MemoryBuffer> buffer;
   if (get_view) {
-    const void *view;
     if (get_view(file->handle, &view) != LDPS_OK) {
       (*message)(LDPL_ERROR, "Failed to get a view of %s", file->name);
       return LDPS_ERR;
     }
-    M = lto_module_create_from_memory(view, file->filesize);
-  } else if (file->offset) {
+  } else {
+    int64_t offset = 0;
     // Gold has found what might be IR part-way inside of a file, such as
     // an .a archive.
-    M = lto_module_create_from_fd_at_offset(file->fd, file->name, -1,
-                                            file->filesize, file->offset);
-  } else {
-    M = lto_module_create_from_fd(file->fd, file->name, file->filesize);
+    if (file->offset) {
+      offset = file->offset;
+    }
+    if (error_code ec =
+        MemoryBuffer::getOpenFile(file->fd, file->name, buffer, file->filesize,
+                                  -1, offset, false)) {
+      (*message)(LDPL_ERROR, ec.message().c_str());
+      return LDPS_ERR;
+    }
+    view = buffer->getBufferStart();
   }
+
+  if (!lto_module_is_object_file_in_memory(view, file->filesize))
+    return LDPS_OK;
+
+  M = lto_module_create_from_memory(view, file->filesize);
   if (!M) {
     if (const char* msg = lto_get_error_message()) {
-      (*message)(LDPL_ERROR, "Failed to create LTO module: %s", msg);
+      (*message)(LDPL_ERROR,
+                 "LLVM gold plugin has failed to create LTO module: %s",
+                 msg);
       return LDPS_ERR;
     }
     return LDPS_OK;