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:
parent
1cd89d625c
commit
36cbde673b
@ -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.");
|
||||||
|
Loading…
Reference in New Issue
Block a user