aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm-c/lto.h8
-rw-r--r--include/llvm/Support/MemoryBuffer.h3
-rw-r--r--lib/Support/MemoryBuffer.cpp15
-rw-r--r--tools/gold/gold-plugin.cpp30
-rw-r--r--tools/lto/LTOModule.cpp11
-rw-r--r--tools/lto/LTOModule.h3
-rw-r--r--tools/lto/lto.cpp8
-rw-r--r--tools/lto/lto.exports1
8 files changed, 58 insertions, 21 deletions
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index 08c12af..1c42ce0 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -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.
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index fa19423..b6243b7 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -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);
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index b7d70dd..a0c650d 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -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) {
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 1639ac1..257c766 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -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());
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index e2ecabc..ca937bf 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -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
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index a19acc0..1794d81 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -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);
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index 75b40f4..7d4871d 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -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
diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports
index 4dbf760..a374091 100644
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -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