1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

add support for .a files containing LLVM IR to the gold plugin

llvm-svn: 63741
This commit is contained in:
Torok Edwin 2009-02-04 17:39:30 +00:00
parent 1cd89d625c
commit 36cbde673b

View File

@ -23,6 +23,7 @@
#include <cstring> #include <cstring>
#include <list> #include <list>
#include <vector> #include <vector>
#include <cerrno>
using namespace llvm; using namespace llvm;
@ -44,6 +45,7 @@ namespace {
struct claimed_file { struct claimed_file {
lto_module_t M; lto_module_t M;
void *handle; void *handle;
void *buf;
std::vector<ld_plugin_symbol> syms; std::vector<ld_plugin_symbol> syms;
}; };
@ -155,19 +157,49 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
/// with add_symbol if possible. /// with add_symbol if possible.
ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
int *claimed) { 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 // 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. // IR in ELF, so we know it's not us. But it can also be an .a file containing
if (file->offset) // LLVM IR.
return LDPS_OK; if (file->offset) {
if (lseek(file->fd, file->offset, SEEK_SET) == -1) {
if (!lto_module_is_object_file(file->name)) (*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; return LDPS_OK;
*claimed = 1; *claimed = 1;
Modules.resize(Modules.size() + 1); Modules.resize(Modules.size() + 1);
claimed_file &cf = Modules.back(); 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) { if (!cf.M) {
(*message)(LDPL_ERROR, "Failed to create LLVM module: %s", (*message)(LDPL_ERROR, "Failed to create LLVM module: %s",
lto_get_error_message()); lto_get_error_message());
@ -201,6 +233,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
break; break;
default: default:
(*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope); (*message)(LDPL_ERROR, "Unknown scope attribute: %d", scope);
free(buf);
return LDPS_ERR; return LDPS_ERR;
} }
@ -220,6 +253,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
break; break;
default: default:
(*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition); (*message)(LDPL_ERROR, "Unknown definition attribute: %d", definition);
free(buf);
return LDPS_ERR; return LDPS_ERR;
} }
@ -235,6 +269,7 @@ ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
if (!cf.syms.empty()) { if (!cf.syms.empty()) {
if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { if ((*add_symbols)(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) {
(*message)(LDPL_ERROR, "Unable to add symbols!"); (*message)(LDPL_ERROR, "Unable to add symbols!");
free(buf);
return LDPS_ERR; return LDPS_ERR;
} }
} }
@ -303,6 +338,10 @@ ld_plugin_status all_symbols_read_hook(void) {
objFile->close(); objFile->close();
lto_codegen_dispose(cg); 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) { if ((*add_input_file)(const_cast<char*>(uniqueObjPath.c_str())) != LDPS_OK) {
(*message)(LDPL_ERROR, "Unable to add .o file to the link."); (*message)(LDPL_ERROR, "Unable to add .o file to the link.");