diff options
Diffstat (limited to 'contrib/llvm/lib/Archive')
-rw-r--r-- | contrib/llvm/lib/Archive/Archive.cpp | 54 | ||||
-rw-r--r-- | contrib/llvm/lib/Archive/ArchiveInternals.h | 2 | ||||
-rw-r--r-- | contrib/llvm/lib/Archive/ArchiveWriter.cpp | 117 |
3 files changed, 97 insertions, 76 deletions
diff --git a/contrib/llvm/lib/Archive/Archive.cpp b/contrib/llvm/lib/Archive/Archive.cpp index 54c715c..1eab27d 100644 --- a/contrib/llvm/lib/Archive/Archive.cpp +++ b/contrib/llvm/lib/Archive/Archive.cpp @@ -15,8 +15,10 @@ #include "ArchiveInternals.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Module.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Process.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/system_error.h" #include <memory> #include <cstring> using namespace llvm; @@ -65,8 +67,9 @@ ArchiveMember::ArchiveMember(Archive* PAR) // different file, presumably as an update to the member. It also makes sure // the flags are reset correctly. bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { - if (!newFile.exists()) { - if (ErrMsg) + bool Exists; + if (sys::fs::exists(newFile.str(), Exists) || !Exists) { + if (ErrMsg) *ErrMsg = "Can not replace an archive member with a non-existent file"; return true; } @@ -113,11 +116,10 @@ bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) { // Get the signature and status info const char* signature = (const char*) data; - std::string magic; + SmallString<4> magic; if (!signature) { - path.getMagicNumber(magic,4); + sys::fs::get_magic(path.str(), magic.capacity(), magic); signature = magic.c_str(); - std::string err; const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg); if (FSinfo) info = *FSinfo; @@ -147,9 +149,13 @@ Archive::Archive(const sys::Path& filename, LLVMContext& C) bool Archive::mapToMemory(std::string* ErrMsg) { - mapfile = MemoryBuffer::getFile(archPath.c_str(), ErrMsg); - if (mapfile == 0) + OwningPtr<MemoryBuffer> File; + if (error_code ec = MemoryBuffer::getFile(archPath.c_str(), File)) { + if (ErrMsg) + *ErrMsg = ec.message(); return true; + } + mapfile = File.take(); base = mapfile->getBufferStart(); return false; } @@ -159,19 +165,19 @@ void Archive::cleanUpMemory() { delete mapfile; mapfile = 0; base = 0; - + // Forget the entire symbol table symTab.clear(); symTabSize = 0; - + firstFileOffset = 0; - + // Free the foreign symbol table member if (foreignST) { delete foreignST; foreignST = 0; } - + // Delete any Modules and ArchiveMember's we've allocated as a result of // symbol table searches. for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) { @@ -193,7 +199,7 @@ static void getSymbols(Module*M, std::vector<std::string>& symbols) { if (!GI->isDeclaration() && !GI->hasLocalLinkage()) if (!GI->getName().empty()) symbols.push_back(GI->getName()); - + // Loop over functions for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) if (!FI->isDeclaration() && !FI->hasLocalLinkage()) @@ -213,20 +219,20 @@ bool llvm::GetBitcodeSymbols(const sys::Path& fName, LLVMContext& Context, std::vector<std::string>& symbols, std::string* ErrMsg) { - std::auto_ptr<MemoryBuffer> Buffer( - MemoryBuffer::getFileOrSTDIN(fName.c_str())); - if (!Buffer.get()) { - if (ErrMsg) *ErrMsg = "Could not open file '" + fName.str() + "'"; + OwningPtr<MemoryBuffer> Buffer; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(fName.c_str(), Buffer)) { + if (ErrMsg) *ErrMsg = "Could not open file '" + fName.str() + "'" + ": " + + ec.message(); return true; } - + Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg); if (!M) return true; - + // Get the symbols getSymbols(M, symbols); - + // Done with the module. delete M; return true; @@ -239,16 +245,16 @@ llvm::GetBitcodeSymbols(const char *BufPtr, unsigned Length, std::vector<std::string>& symbols, std::string* ErrMsg) { // Get the module. - std::auto_ptr<MemoryBuffer> Buffer( + OwningPtr<MemoryBuffer> Buffer( MemoryBuffer::getMemBufferCopy(StringRef(BufPtr, Length),ModuleID.c_str())); - + Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg); if (!M) return 0; - + // Get the symbols getSymbols(M, symbols); - + // Done with the module. Note that it's the caller's responsibility to delete // the Module. return M; diff --git a/contrib/llvm/lib/Archive/ArchiveInternals.h b/contrib/llvm/lib/Archive/ArchiveInternals.h index 08f20e7..55684f7 100644 --- a/contrib/llvm/lib/Archive/ArchiveInternals.h +++ b/contrib/llvm/lib/Archive/ArchiveInternals.h @@ -15,7 +15,7 @@ #define LIB_ARCHIVE_ARCHIVEINTERNALS_H #include "llvm/Bitcode/Archive.h" -#include "llvm/System/TimeValue.h" +#include "llvm/Support/TimeValue.h" #include "llvm/ADT/StringExtras.h" #include <cstring> diff --git a/contrib/llvm/lib/Archive/ArchiveWriter.cpp b/contrib/llvm/lib/Archive/ArchiveWriter.cpp index 7eeeb59..c5ad5fc 100644 --- a/contrib/llvm/lib/Archive/ArchiveWriter.cpp +++ b/contrib/llvm/lib/Archive/ArchiveWriter.cpp @@ -15,9 +15,12 @@ #include "llvm/Module.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Process.h" -#include "llvm/System/Signals.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h" #include <fstream> #include <ostream> #include <iomanip> @@ -25,7 +28,7 @@ using namespace llvm; // Write an integer using variable bit rate encoding. This saves a few bytes // per entry in the symbol table. -static inline void writeInteger(unsigned num, std::ofstream& ARFile) { +static inline void writeInteger(unsigned num, raw_ostream& ARFile) { while (1) { if (num < 0x80) { // done? ARFile << (unsigned char)num; @@ -153,9 +156,10 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr, // Insert a file into the archive before some other member. This also takes care // of extracting the necessary flags and information from the file. bool -Archive::addFileBefore(const sys::Path& filePath, iterator where, +Archive::addFileBefore(const sys::Path& filePath, iterator where, std::string* ErrMsg) { - if (!filePath.exists()) { + bool Exists; + if (sys::fs::exists(filePath.str(), Exists) || !Exists) { if (ErrMsg) *ErrMsg = "Can not add a non-existent file to archive"; return true; @@ -178,9 +182,11 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where, flags |= ArchiveMember::HasPathFlag; if (hasSlash || filePath.str().length() > 15) flags |= ArchiveMember::HasLongFilenameFlag; - std::string magic; - mbr->path.getMagicNumber(magic,4); - switch (sys::IdentifyFileType(magic.c_str(),4)) { + + sys::LLVMFileType type; + if (sys::fs::identify_magic(mbr->path.str(), type)) + type = sys::Unknown_FileType; + switch (type) { case sys::Bitcode_FileType: flags |= ArchiveMember::BitcodeFlag; break; @@ -196,14 +202,14 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where, bool Archive::writeMember( const ArchiveMember& member, - std::ofstream& ARFile, + raw_ostream& ARFile, bool CreateSymbolTable, bool TruncateNames, bool ShouldCompress, std::string* ErrMsg ) { - unsigned filepos = ARFile.tellp(); + unsigned filepos = ARFile.tell(); filepos -= 8; // Get the data and its size either from the @@ -212,9 +218,13 @@ Archive::writeMember( const char *data = (const char*)member.getData(); MemoryBuffer *mFile = 0; if (!data) { - mFile = MemoryBuffer::getFile(member.getPath().c_str(), ErrMsg); - if (mFile == 0) + OwningPtr<MemoryBuffer> File; + if (error_code ec = MemoryBuffer::getFile(member.getPath().c_str(), File)) { + if (ErrMsg) + *ErrMsg = ec.message(); return true; + } + mFile = File.take(); data = mFile->getBufferStart(); fSize = mFile->getBufferSize(); } @@ -225,7 +235,7 @@ Archive::writeMember( std::vector<std::string> symbols; std::string FullMemberName = archPath.str() + "(" + member.getPath().str() + ")"; - Module* M = + Module* M = GetBitcodeSymbols(data, fSize, FullMemberName, Context, symbols, ErrMsg); // If the bitcode parsed successfully @@ -272,7 +282,7 @@ Archive::writeMember( ARFile.write(data,fSize); // Make sure the member is an even length - if ((ARFile.tellp() & 1) == 1) + if ((ARFile.tell() & 1) == 1) ARFile << ARFILE_PAD; // Close the mapped file if it was opened @@ -282,7 +292,7 @@ Archive::writeMember( // Write out the LLVM symbol table as an archive member to the file. void -Archive::writeSymbolTable(std::ofstream& ARFile) { +Archive::writeSymbolTable(raw_ostream& ARFile) { // Construct the symbol table's header ArchiveMemberHeader Hdr; @@ -306,7 +316,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) { #ifndef NDEBUG // Save the starting position of the symbol tables data content. - unsigned startpos = ARFile.tellp(); + unsigned startpos = ARFile.tell(); #endif // Write out the symbols sequentially @@ -323,7 +333,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) { #ifndef NDEBUG // Now that we're done with the symbol table, get the ending file position - unsigned endpos = ARFile.tellp(); + unsigned endpos = ARFile.tell(); #endif // Make sure that the amount we wrote is what we pre-computed. This is @@ -352,25 +362,20 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, } // Create a temporary file to store the archive in - sys::Path TmpArchive = archPath; - if (TmpArchive.createTemporaryFileOnDisk(ErrMsg)) + SmallString<128> TempArchivePath; + int ArchFD; + if (error_code ec = + sys::fs::unique_file("%%-%%-%%-%%-" + sys::path::filename(archPath.str()), + ArchFD, TempArchivePath)) { + if (ErrMsg) *ErrMsg = ec.message(); return true; + } // Make sure the temporary gets removed if we crash - sys::RemoveFileOnSignal(TmpArchive); + sys::RemoveFileOnSignal(sys::Path(TempArchivePath.str())); // Create archive file for output. - std::ios::openmode io_mode = std::ios::out | std::ios::trunc | - std::ios::binary; - std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode); - - // Check for errors opening or creating archive file. - if (!ArchiveFile.is_open() || ArchiveFile.bad()) { - TmpArchive.eraseFromDisk(); - if (ErrMsg) - *ErrMsg = "Error opening archive file: " + archPath.str(); - return true; - } + raw_fd_ostream ArchiveFile(ArchFD, true); // If we're creating a symbol table, reset it now if (CreateSymbolTable) { @@ -386,8 +391,9 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, for (MembersList::iterator I = begin(), E = end(); I != E; ++I) { if (writeMember(*I, ArchiveFile, CreateSymbolTable, TruncateNames, Compress, ErrMsg)) { - TmpArchive.eraseFromDisk(); ArchiveFile.close(); + bool existed; + sys::fs::remove(TempArchivePath.str(), existed); return true; } } @@ -402,27 +408,29 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // ensure compatibility with other archivers we need to put the symbol // table first in the file. Unfortunately, this means mapping the file // we just wrote back in and copying it to the destination file. - sys::Path FinalFilePath = archPath; + SmallString<128> TempArchiveWithSymbolTablePath; // Map in the archive we just wrote. { - OwningPtr<MemoryBuffer> arch(MemoryBuffer::getFile(TmpArchive.c_str())); - if (arch == 0) return true; + OwningPtr<MemoryBuffer> arch; + if (error_code ec = MemoryBuffer::getFile(TempArchivePath.c_str(), arch)) { + if (ErrMsg) + *ErrMsg = ec.message(); + return true; + } const char* base = arch->getBufferStart(); - // Open another temporary file in order to avoid invalidating the + // Open another temporary file in order to avoid invalidating the // mmapped data - if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg)) - return true; - sys::RemoveFileOnSignal(FinalFilePath); - - std::ofstream FinalFile(FinalFilePath.c_str(), io_mode); - if (!FinalFile.is_open() || FinalFile.bad()) { - TmpArchive.eraseFromDisk(); - if (ErrMsg) - *ErrMsg = "Error opening archive file: " + FinalFilePath.str(); + if (error_code ec = + sys::fs::unique_file("%%-%%-%%-%%-" + sys::path::filename(archPath.str()), + ArchFD, TempArchiveWithSymbolTablePath)) { + if (ErrMsg) *ErrMsg = ec.message(); return true; } + sys::RemoveFileOnSignal(sys::Path(TempArchiveWithSymbolTablePath.str())); + + raw_fd_ostream FinalFile(ArchFD, true); // Write the file magic number FinalFile << ARFILE_MAGIC; @@ -435,7 +443,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, if (foreignST) { if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) { FinalFile.close(); - TmpArchive.eraseFromDisk(); + bool existed; + sys::fs::remove(TempArchiveWithSymbolTablePath.str(), existed); return true; } } @@ -451,19 +460,25 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress, // Close up shop FinalFile.close(); } // free arch. - + // Move the final file over top of TmpArchive - if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg)) + if (error_code ec = sys::fs::rename(TempArchiveWithSymbolTablePath.str(), + TempArchivePath.str())) { + if (ErrMsg) *ErrMsg = ec.message(); return true; + } } - + // Before we replace the actual archive, we need to forget all the // members, since they point to data in that old archive. We need to do // this because we cannot replace an open file on Windows. cleanUpMemory(); - - if (TmpArchive.renamePathOnDisk(archPath, ErrMsg)) + + if (error_code ec = sys::fs::rename(TempArchivePath.str(), + archPath.str())) { + if (ErrMsg) *ErrMsg = ec.message(); return true; + } // Set correct read and write permissions after temporary file is moved // to final destination path. |