mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Fix massive resource leaks in the bytecode reader. Reading a bytecode file
with ParseBytecodeFile used to leak both a ModuleProvider (and related bytecode parser stuff attached to it) AND a file descriptor, which was never closed. This prevented gccld/llvm-ld/llvm-link from linking together apps with more that ~252 .bc files on darwin. llvm-svn: 30912
This commit is contained in:
parent
b7ff3d59f7
commit
08684eac36
@ -248,6 +248,12 @@ protected:
|
|||||||
/// @brief Parse a string constants block
|
/// @brief Parse a string constants block
|
||||||
void ParseStringConstants(unsigned NumEntries, ValueTable &Tab);
|
void ParseStringConstants(unsigned NumEntries, ValueTable &Tab);
|
||||||
|
|
||||||
|
/// @brief Release our memory.
|
||||||
|
void freeState() {
|
||||||
|
freeTable(FunctionValues);
|
||||||
|
freeTable(ModuleValues);
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Data
|
/// @name Data
|
||||||
/// @{
|
/// @{
|
||||||
@ -467,12 +473,6 @@ private:
|
|||||||
/// given constant.
|
/// given constant.
|
||||||
void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
|
void ResolveReferencesToConstant(Constant *C, unsigned Typ, unsigned Slot);
|
||||||
|
|
||||||
/// @brief Release our memory.
|
|
||||||
void freeState() {
|
|
||||||
freeTable(FunctionValues);
|
|
||||||
freeTable(ModuleValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Free a table, making sure to free the ValueList in the table.
|
/// @brief Free a table, making sure to free the ValueList in the table.
|
||||||
void freeTable(ValueTable &Tab) {
|
void freeTable(ValueTable &Tab) {
|
||||||
while (!Tab.empty()) {
|
while (!Tab.empty()) {
|
||||||
|
@ -44,15 +44,17 @@ namespace {
|
|||||||
public:
|
public:
|
||||||
BytecodeFileReader(const std::string &Filename, llvm::BytecodeHandler* H=0);
|
BytecodeFileReader(const std::string &Filename, llvm::BytecodeHandler* H=0);
|
||||||
bool read(std::string* ErrMsg);
|
bool read(std::string* ErrMsg);
|
||||||
|
|
||||||
|
void freeState() {
|
||||||
|
BytecodeReader::freeState();
|
||||||
|
mapFile.close();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
|
BytecodeFileReader::BytecodeFileReader(const std::string &Filename,
|
||||||
llvm::BytecodeHandler* H )
|
llvm::BytecodeHandler* H)
|
||||||
: BytecodeReader(H)
|
: BytecodeReader(H), fileName(Filename) {
|
||||||
, fileName(Filename)
|
|
||||||
, mapFile()
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BytecodeFileReader::read(std::string* ErrMsg) {
|
bool BytecodeFileReader::read(std::string* ErrMsg) {
|
||||||
@ -63,10 +65,7 @@ bool BytecodeFileReader::read(std::string* ErrMsg) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
unsigned char* buffer = reinterpret_cast<unsigned char*>(mapFile.base());
|
unsigned char* buffer = reinterpret_cast<unsigned char*>(mapFile.base());
|
||||||
if (ParseBytecode(buffer, mapFile.size(), fileName, ErrMsg)) {
|
return ParseBytecode(buffer, mapFile.size(), fileName, ErrMsg);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -101,14 +100,9 @@ namespace {
|
|||||||
BytecodeBufferReader::BytecodeBufferReader(const unsigned char *buf,
|
BytecodeBufferReader::BytecodeBufferReader(const unsigned char *buf,
|
||||||
unsigned len,
|
unsigned len,
|
||||||
const std::string &modID,
|
const std::string &modID,
|
||||||
llvm::BytecodeHandler* H)
|
llvm::BytecodeHandler *H)
|
||||||
: BytecodeReader(H)
|
: BytecodeReader(H), Buffer(0), Buf(buf), Length(len), ModuleID(modID)
|
||||||
, Buffer(0)
|
, MustDelete(false) {
|
||||||
, Buf(buf)
|
|
||||||
, Length(len)
|
|
||||||
, ModuleID(modID)
|
|
||||||
, MustDelete(false)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BytecodeBufferReader::~BytecodeBufferReader() {
|
BytecodeBufferReader::~BytecodeBufferReader() {
|
||||||
@ -300,8 +294,8 @@ ModuleProvider*
|
|||||||
llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
|
llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
|
||||||
unsigned Length,
|
unsigned Length,
|
||||||
const std::string &ModuleID,
|
const std::string &ModuleID,
|
||||||
std::string* ErrMsg,
|
std::string *ErrMsg,
|
||||||
BytecodeHandler* H) {
|
BytecodeHandler *H) {
|
||||||
BytecodeBufferReader* rdr =
|
BytecodeBufferReader* rdr =
|
||||||
new BytecodeBufferReader(Buffer, Length, ModuleID, H);
|
new BytecodeBufferReader(Buffer, Length, ModuleID, H);
|
||||||
if (rdr->read(ErrMsg))
|
if (rdr->read(ErrMsg))
|
||||||
@ -313,12 +307,13 @@ llvm::getBytecodeBufferModuleProvider(const unsigned char *Buffer,
|
|||||||
///
|
///
|
||||||
Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
|
Module *llvm::ParseBytecodeBuffer(const unsigned char *Buffer, unsigned Length,
|
||||||
const std::string &ModuleID,
|
const std::string &ModuleID,
|
||||||
std::string *ErrMsg){
|
std::string *ErrMsg) {
|
||||||
ModuleProvider* MP =
|
ModuleProvider *MP =
|
||||||
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, 0);
|
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, 0);
|
||||||
if (!MP)
|
if (!MP) return 0;
|
||||||
return 0;
|
Module *M = MP->releaseModule();
|
||||||
return MP->releaseModule();
|
delete MP;
|
||||||
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
|
/// getBytecodeModuleProvider - lazy function-at-a-time loading from a file
|
||||||
@ -347,9 +342,10 @@ llvm::getBytecodeModuleProvider(const std::string &Filename,
|
|||||||
Module *llvm::ParseBytecodeFile(const std::string &Filename,
|
Module *llvm::ParseBytecodeFile(const std::string &Filename,
|
||||||
std::string *ErrMsg) {
|
std::string *ErrMsg) {
|
||||||
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg);
|
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg);
|
||||||
if (!MP)
|
if (!MP) return 0;
|
||||||
return 0;
|
Module *M = MP->releaseModule();
|
||||||
return MP->releaseModule();
|
delete MP;
|
||||||
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnalyzeBytecodeFile - analyze one file
|
// AnalyzeBytecodeFile - analyze one file
|
||||||
@ -358,13 +354,13 @@ Module* llvm::AnalyzeBytecodeFile(
|
|||||||
BytecodeAnalysis& bca, ///< Statistical output
|
BytecodeAnalysis& bca, ///< Statistical output
|
||||||
std::string *ErrMsg, ///< Error output
|
std::string *ErrMsg, ///< Error output
|
||||||
std::ostream* output ///< Dump output
|
std::ostream* output ///< Dump output
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
BytecodeHandler* AH = createBytecodeAnalyzerHandler(bca,output);
|
BytecodeHandler* AH = createBytecodeAnalyzerHandler(bca,output);
|
||||||
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg, AH);
|
ModuleProvider* MP = getBytecodeModuleProvider(Filename, ErrMsg, AH);
|
||||||
if (!MP)
|
if (!MP) return 0;
|
||||||
return 0;
|
Module *M = MP->releaseModule();
|
||||||
return MP->releaseModule();
|
delete MP;
|
||||||
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnalyzeBytecodeBuffer - analyze a buffer
|
// AnalyzeBytecodeBuffer - analyze a buffer
|
||||||
@ -380,15 +376,16 @@ Module* llvm::AnalyzeBytecodeBuffer(
|
|||||||
BytecodeHandler* hdlr = createBytecodeAnalyzerHandler(bca, output);
|
BytecodeHandler* hdlr = createBytecodeAnalyzerHandler(bca, output);
|
||||||
ModuleProvider* MP =
|
ModuleProvider* MP =
|
||||||
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, hdlr);
|
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID, ErrMsg, hdlr);
|
||||||
if (!MP)
|
if (!MP) return 0;
|
||||||
return 0;
|
Module *M = MP->releaseModule();
|
||||||
return MP->releaseModule();
|
delete MP;
|
||||||
|
return M;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
|
bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
|
||||||
Module::LibraryListType& deplibs,
|
Module::LibraryListType& deplibs,
|
||||||
std::string* ErrMsg) {
|
std::string* ErrMsg) {
|
||||||
ModuleProvider* MP = getBytecodeModuleProvider(fname, ErrMsg);
|
ModuleProvider* MP = getBytecodeModuleProvider(fname, ErrMsg);
|
||||||
if (!MP) {
|
if (!MP) {
|
||||||
deplibs.clear();
|
deplibs.clear();
|
||||||
return true;
|
return true;
|
||||||
@ -396,6 +393,7 @@ bool llvm::GetBytecodeDependentLibraries(const std::string &fname,
|
|||||||
Module* M = MP->releaseModule();
|
Module* M = MP->releaseModule();
|
||||||
deplibs = M->getLibraries();
|
deplibs = M->getLibraries();
|
||||||
delete M;
|
delete M;
|
||||||
|
delete MP;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,19 +415,22 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) {
|
|||||||
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
||||||
std::vector<std::string>& symbols,
|
std::vector<std::string>& symbols,
|
||||||
std::string* ErrMsg) {
|
std::string* ErrMsg) {
|
||||||
ModuleProvider* MP = getBytecodeModuleProvider(fName.toString(), ErrMsg);
|
ModuleProvider *MP = getBytecodeModuleProvider(fName.toString(), ErrMsg);
|
||||||
if (!MP)
|
if (!MP)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Get the module from the provider
|
// Get the module from the provider
|
||||||
Module* M = MP->materializeModule();
|
Module* M = MP->materializeModule();
|
||||||
if (M == 0)
|
if (M == 0) {
|
||||||
|
delete MP;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the symbols
|
// Get the symbols
|
||||||
getSymbols(M, symbols);
|
getSymbols(M, symbols);
|
||||||
|
|
||||||
// Done with the module
|
// Done with the module.
|
||||||
|
delete MP;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user