diff options
author | Torok Edwin <edwintorok@gmail.com> | 2009-02-04 17:39:30 +0000 |
---|---|---|
committer | Torok Edwin <edwintorok@gmail.com> | 2009-02-04 17:39:30 +0000 |
commit | 3e5a0d8b0b848d1b0deb8976924703787b221e31 (patch) | |
tree | ff391c2d314457482cca05ef5c6232698332033c /tools | |
parent | 37eed798a94b6e4160cc4fc5b239d24707556f9e (diff) | |
download | external_llvm-3e5a0d8b0b848d1b0deb8976924703787b221e31.zip external_llvm-3e5a0d8b0b848d1b0deb8976924703787b221e31.tar.gz external_llvm-3e5a0d8b0b848d1b0deb8976924703787b221e31.tar.bz2 |
add support for .a files containing LLVM IR to the gold plugin
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63741 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gold/gold-plugin.cpp | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 8c4bf04..afd7fd6 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -23,6 +23,7 @@ #include <cstring> #include <list> #include <vector> +#include <cerrno> using namespace llvm; @@ -44,6 +45,7 @@ namespace { struct claimed_file { lto_module_t M; void *handle; + void *buf; std::vector<ld_plugin_symbol> syms; }; @@ -155,19 +157,49 @@ ld_plugin_status onload(ld_plugin_tv *tv) { /// with add_symbol if possible. ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, int *claimed) { + void *buf = NULL; + printf("%s,%d,%d\n",file->name, file->offset, file->filesize); // If set, this means gold found IR in an ELF section. LLVM doesn't wrap its - // IR in ELF, so we know it's not us. - if (file->offset) - return LDPS_OK; - - if (!lto_module_is_object_file(file->name)) + // IR in ELF, so we know it's not us. But it can also be an .a file containing + // LLVM IR. + if (file->offset) { + if (lseek(file->fd, file->offset, SEEK_SET) == -1) { + (*message)(LDPL_ERROR, + "Failed to seek to archive member of %s at offset %d: %s\n", + file->name, + file->offset, strerror(errno)); + return LDPS_ERR; + } + buf = malloc(file->filesize); + if (!buf) { + (*message)(LDPL_ERROR, + "Failed to allocate buffer for archive member of size: %d\n", + file->filesize); + return LDPS_ERR; + } + if (read(file->fd, buf, file->filesize) != file->filesize) { + (*message)(LDPL_ERROR, + "Failed to read archive member of %s at offset %d: %s\n", + file->name, + file->offset, + strerror(errno)); + free(buf); + return LDPS_ERR; + } + if (!lto_module_is_object_file_in_memory(buf, file->filesize)) { + free(buf); + return LDPS_OK; + } + } else if (!lto_module_is_object_file(file->name)) return LDPS_OK; *claimed = 1; Modules.resize(Modules.size() + 1); claimed_file &cf = Modules.back(); - cf.M = lto_module_create(file->name); + cf.M = buf ? lto_module_create_from_memory(buf, file->filesize) : + lto_module_create(file->name); + cf.buf = buf; if (!cf.M) { (*message)(LDPL_ERROR, "Failed to create LLVM module: %s", lto_get_error_message()); @@ -201,6 +233,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, break; default: (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); + free(buf); return LDPS_ERR; } @@ -220,6 +253,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, break; default: (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); + free(buf); return LDPS_ERR; } @@ -235,6 +269,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, if (!cf.syms.empty()) { if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to add symbols!"); + free(buf); return LDPS_ERR; } } @@ -303,6 +338,10 @@ ld_plugin_status all_symbols_read_hook(void) { objFile->close(); lto_codegen_dispose(cg); + for (std::list<claimed_file>::iterator I = Modules.begin(), + E = Modules.end(); I != E; ++I) { + free(I->buf); + } if ((*add_input_file)(const_cast<char*>(uniqueObjPath.c_str())) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to add .o file to the link."); |