mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 22:20:37 +00:00
Don't open the file again in the gold plugin. To be able to do this, update
MemoryBuffer::getOpenFile to not close the file descriptor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125128 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
971b83b67a
commit
b4cc031a3e
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define LTO_API_VERSION 4
|
#define LTO_API_VERSION 4
|
||||||
|
|
||||||
@ -121,6 +122,13 @@ lto_module_create(const char* path);
|
|||||||
extern lto_module_t
|
extern lto_module_t
|
||||||
lto_module_create_from_memory(const void* mem, size_t length);
|
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.
|
* Frees all memory internally allocated by the module.
|
||||||
|
@ -69,8 +69,7 @@ public:
|
|||||||
int64_t FileSize = -1);
|
int64_t FileSize = -1);
|
||||||
|
|
||||||
/// getOpenFile - Given an already-open file descriptor, read the file and
|
/// getOpenFile - Given an already-open file descriptor, read the file and
|
||||||
/// return a MemoryBuffer. This takes ownership of the descriptor,
|
/// return a MemoryBuffer.
|
||||||
/// immediately closing it after reading the file.
|
|
||||||
static error_code getOpenFile(int FD, const char *Filename,
|
static error_code getOpenFile(int FD, const char *Filename,
|
||||||
OwningPtr<MemoryBuffer> &result,
|
OwningPtr<MemoryBuffer> &result,
|
||||||
int64_t FileSize = -1);
|
int64_t FileSize = -1);
|
||||||
|
@ -179,14 +179,6 @@ public:
|
|||||||
sys::Path::UnMapFilePages(getBufferStart(), getBufferSize());
|
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,
|
error_code MemoryBuffer::getFile(StringRef Filename,
|
||||||
@ -208,15 +200,14 @@ error_code MemoryBuffer::getFile(const char *Filename,
|
|||||||
if (FD == -1) {
|
if (FD == -1) {
|
||||||
return error_code(errno, posix_category());
|
return error_code(errno, posix_category());
|
||||||
}
|
}
|
||||||
|
error_code ret = getOpenFile(FD, Filename, result, FileSize);
|
||||||
return getOpenFile(FD, Filename, result, FileSize);
|
close(FD);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
|
error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
|
||||||
OwningPtr<MemoryBuffer> &result,
|
OwningPtr<MemoryBuffer> &result,
|
||||||
int64_t FileSize) {
|
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
|
// 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.
|
// file descriptor is cheaper than stat on a random path.
|
||||||
if (FileSize == -1) {
|
if (FileSize == -1) {
|
||||||
|
@ -241,7 +241,8 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
|
|||||||
/// with add_symbol if possible.
|
/// with add_symbol if possible.
|
||||||
static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
|
static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
|
||||||
int *claimed) {
|
int *claimed) {
|
||||||
void *buf = NULL;
|
lto_module_t M;
|
||||||
|
|
||||||
if (file->offset) {
|
if (file->offset) {
|
||||||
// Gold has found what might be IR part-way inside of a file, such as
|
// Gold has found what might be IR part-way inside of a file, such as
|
||||||
// an .a archive.
|
// 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());
|
file->offset, sys::StrError(errno).c_str());
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
}
|
}
|
||||||
buf = malloc(file->filesize);
|
void *buf = malloc(file->filesize);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
(*message)(LDPL_ERROR,
|
(*message)(LDPL_ERROR,
|
||||||
"Failed to allocate buffer for archive member of size: %d\n",
|
"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);
|
free(buf);
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
}
|
}
|
||||||
} else if (!lto_module_is_object_file(file->name))
|
M = lto_module_create_from_memory(buf, file->filesize);
|
||||||
return LDPS_OK;
|
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;
|
*claimed = 1;
|
||||||
Modules.resize(Modules.size() + 1);
|
Modules.resize(Modules.size() + 1);
|
||||||
claimed_file &cf = Modules.back();
|
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) {
|
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());
|
||||||
|
@ -87,6 +87,17 @@ LTOModule *LTOModule::makeLTOModule(const char *path,
|
|||||||
return makeLTOModule(buffer.get(), errMsg);
|
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
|
/// 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
|
/// 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
|
/// and already be that way, otherwise make a copy. Also if next byte is on a
|
||||||
|
@ -51,6 +51,9 @@ struct LTOModule {
|
|||||||
|
|
||||||
static LTOModule* makeLTOModule(const char* path,
|
static LTOModule* makeLTOModule(const char* path,
|
||||||
std::string& errMsg);
|
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,
|
static LTOModule* makeLTOModule(const void* mem, size_t length,
|
||||||
std::string& errMsg);
|
std::string& errMsg);
|
||||||
|
|
||||||
|
@ -91,6 +91,14 @@ lto_module_t lto_module_create(const char* path)
|
|||||||
return LTOModule::makeLTOModule(path, sLastErrorString);
|
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
|
// loads an object file from memory
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
lto_get_error_message
|
lto_get_error_message
|
||||||
lto_get_version
|
lto_get_version
|
||||||
lto_module_create
|
lto_module_create
|
||||||
|
lto_module_create_from_fd
|
||||||
lto_module_create_from_memory
|
lto_module_create_from_memory
|
||||||
lto_module_get_num_symbols
|
lto_module_get_num_symbols
|
||||||
lto_module_get_symbol_attribute
|
lto_module_get_symbol_attribute
|
||||||
|
Loading…
Reference in New Issue
Block a user