diff options
-rw-r--r-- | include/llvm-c/lto.h | 8 | ||||
-rw-r--r-- | include/llvm/Support/MemoryBuffer.h | 3 | ||||
-rw-r--r-- | lib/Support/MemoryBuffer.cpp | 15 | ||||
-rw-r--r-- | tools/gold/gold-plugin.cpp | 30 | ||||
-rw-r--r-- | tools/lto/LTOModule.cpp | 11 | ||||
-rw-r--r-- | tools/lto/LTOModule.h | 3 | ||||
-rw-r--r-- | tools/lto/lto.cpp | 8 | ||||
-rw-r--r-- | tools/lto/lto.exports | 1 |
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 |