mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
For PR797:
Remove exception handling from the bytecode archiver and adjust the llvm-ar tool to accommodate the new interfaces. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29866 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c82b3aab65
commit
0ff2d31766
@ -167,8 +167,9 @@ class ArchiveMember {
|
|||||||
/// of the file specified by \p File. The contents of \p this will be
|
/// of the file specified by \p File. The contents of \p this will be
|
||||||
/// updated to reflect the new data from \p File. The \p File must exist and
|
/// updated to reflect the new data from \p File. The \p File must exist and
|
||||||
/// be readable on entry to this method.
|
/// be readable on entry to this method.
|
||||||
|
/// @returns true if an error occurred, false otherwise
|
||||||
/// @brief Replace contents of archive member with a new file.
|
/// @brief Replace contents of archive member with a new file.
|
||||||
void replaceWith(const sys::Path &aFile);
|
bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name ilist methods - do not use
|
/// @name ilist methods - do not use
|
||||||
@ -439,8 +440,8 @@ class Archive {
|
|||||||
/// name will be truncated at 15 characters. If \p Compress is specified,
|
/// name will be truncated at 15 characters. If \p Compress is specified,
|
||||||
/// all archive members will be compressed before being written. If
|
/// all archive members will be compressed before being written. If
|
||||||
/// \p PrintSymTab is true, the symbol table will be printed to std::cout.
|
/// \p PrintSymTab is true, the symbol table will be printed to std::cout.
|
||||||
/// @returns false if an error occurred, \p error set to error message
|
/// @returns true if an error occurred, \p error set to error message
|
||||||
/// @returns true if the writing succeeded.
|
/// @returns false if the writing succeeded.
|
||||||
/// @brief Write (possibly modified) archive contents to disk
|
/// @brief Write (possibly modified) archive contents to disk
|
||||||
bool writeToDisk(
|
bool writeToDisk(
|
||||||
bool CreateSymbolTable=false, ///< Create Symbol table
|
bool CreateSymbolTable=false, ///< Create Symbol table
|
||||||
@ -453,10 +454,13 @@ class Archive {
|
|||||||
/// to determine just enough information to create an ArchiveMember object
|
/// to determine just enough information to create an ArchiveMember object
|
||||||
/// which is then inserted into the Archive object's ilist at the location
|
/// which is then inserted into the Archive object's ilist at the location
|
||||||
/// given by \p where.
|
/// given by \p where.
|
||||||
/// @throws std::string if an error occurs reading the \p filename.
|
/// @returns true if an error occured, false otherwise
|
||||||
/// @returns nothing
|
|
||||||
/// @brief Add a file to the archive.
|
/// @brief Add a file to the archive.
|
||||||
void addFileBefore(const sys::Path& filename, iterator where);
|
bool addFileBefore(
|
||||||
|
const sys::Path& filename, ///< The file to be added
|
||||||
|
iterator where, ///< Insertion point
|
||||||
|
std::string* ErrMsg ///< Optional error message location
|
||||||
|
);
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Implementation
|
/// @name Implementation
|
||||||
@ -464,7 +468,7 @@ class Archive {
|
|||||||
protected:
|
protected:
|
||||||
/// @brief Construct an Archive for \p filename and optionally map it
|
/// @brief Construct an Archive for \p filename and optionally map it
|
||||||
/// into memory.
|
/// into memory.
|
||||||
Archive(const sys::Path& filename, bool map = false );
|
Archive(const sys::Path& filename);
|
||||||
|
|
||||||
/// @param error Set to address of a std::string to get error messages
|
/// @param error Set to address of a std::string to get error messages
|
||||||
/// @returns false on error
|
/// @returns false on error
|
||||||
@ -500,8 +504,8 @@ class Archive {
|
|||||||
/// Writes one ArchiveMember to an ofstream. If an error occurs, returns
|
/// Writes one ArchiveMember to an ofstream. If an error occurs, returns
|
||||||
/// false, otherwise true. If an error occurs and error is non-null then
|
/// false, otherwise true. If an error occurs and error is non-null then
|
||||||
/// it will be set to an error message.
|
/// it will be set to an error message.
|
||||||
/// @returns true Writing member succeeded
|
/// @returns false Writing member succeeded
|
||||||
/// @returns false Writing member failed, \p error set to error message
|
/// @returns true Writing member failed, \p error set to error message
|
||||||
bool writeMember(
|
bool writeMember(
|
||||||
const ArchiveMember& member, ///< The member to be written
|
const ArchiveMember& member, ///< The member to be written
|
||||||
std::ofstream& ARFile, ///< The file to write member onto
|
std::ofstream& ARFile, ///< The file to write member onto
|
||||||
@ -515,6 +519,9 @@ class Archive {
|
|||||||
bool fillHeader(const ArchiveMember&mbr,
|
bool fillHeader(const ArchiveMember&mbr,
|
||||||
ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
|
ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
|
||||||
|
|
||||||
|
/// @brief Maps archive into memory
|
||||||
|
bool mapToMemory(std::string* ErrMsg);
|
||||||
|
|
||||||
/// @brief Frees all the members and unmaps the archive file.
|
/// @brief Frees all the members and unmaps the archive file.
|
||||||
void cleanUpMemory();
|
void cleanUpMemory();
|
||||||
|
|
||||||
@ -525,6 +532,7 @@ class Archive {
|
|||||||
typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> >
|
typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> >
|
||||||
ModuleMap;
|
ModuleMap;
|
||||||
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Data
|
/// @name Data
|
||||||
/// @{
|
/// @{
|
||||||
|
@ -61,7 +61,7 @@ ArchiveMember::ArchiveMember(Archive* PAR)
|
|||||||
// This method allows an ArchiveMember to be replaced with the data for a
|
// This method allows an ArchiveMember to be replaced with the data for a
|
||||||
// different file, presumably as an update to the member. It also makes sure
|
// different file, presumably as an update to the member. It also makes sure
|
||||||
// the flags are reset correctly.
|
// the flags are reset correctly.
|
||||||
void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
|
||||||
assert(newFile.exists() && "Can't replace with a non-existent file");
|
assert(newFile.exists() && "Can't replace with a non-existent file");
|
||||||
data = 0;
|
data = 0;
|
||||||
path = newFile;
|
path = newFile;
|
||||||
@ -110,8 +110,8 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
|||||||
path.getMagicNumber(magic,4);
|
path.getMagicNumber(magic,4);
|
||||||
signature = magic.c_str();
|
signature = magic.c_str();
|
||||||
std::string err;
|
std::string err;
|
||||||
if (path.getFileStatus(info, &err))
|
if (path.getFileStatus(info, ErrMsg))
|
||||||
throw err;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine what kind of file it is
|
// Determine what kind of file it is
|
||||||
@ -127,23 +127,27 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
|||||||
flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
|
flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archive constructor - this is the only constructor that gets used for the
|
// Archive constructor - this is the only constructor that gets used for the
|
||||||
// Archive class. Everything else (default,copy) is deprecated. This just
|
// Archive class. Everything else (default,copy) is deprecated. This just
|
||||||
// initializes and maps the file into memory, if requested.
|
// initializes and maps the file into memory, if requested.
|
||||||
Archive::Archive(const sys::Path& filename, bool map )
|
Archive::Archive(const sys::Path& filename)
|
||||||
: archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
|
: archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
|
||||||
symTabSize(0), firstFileOffset(0), modules(), foreignST(0)
|
symTabSize(0), firstFileOffset(0), modules(), foreignST(0)
|
||||||
{
|
{
|
||||||
if (map) {
|
}
|
||||||
std::string ErrMsg;
|
|
||||||
mapfile = new sys::MappedFile();
|
bool
|
||||||
if (mapfile->open(filename, sys::MappedFile::READ_ACCESS, &ErrMsg))
|
Archive::mapToMemory(std::string* ErrMsg)
|
||||||
throw ErrMsg;
|
{
|
||||||
if (!(base = (char*) mapfile->map(&ErrMsg)))
|
mapfile = new sys::MappedFile();
|
||||||
throw ErrMsg;
|
if (mapfile->open(archPath, sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
}
|
return true;
|
||||||
|
if (!(base = (char*) mapfile->map(ErrMsg)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Archive::cleanUpMemory() {
|
void Archive::cleanUpMemory() {
|
||||||
|
@ -330,7 +330,9 @@ Archive::loadArchive(std::string* error) {
|
|||||||
Archive*
|
Archive*
|
||||||
Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
||||||
{
|
{
|
||||||
std::auto_ptr<Archive> result ( new Archive(file, true));
|
std::auto_ptr<Archive> result ( new Archive(file));
|
||||||
|
if (result->mapToMemory(ErrorMessage))
|
||||||
|
return 0;
|
||||||
if (!result->loadArchive(ErrorMessage))
|
if (!result->loadArchive(ErrorMessage))
|
||||||
return 0;
|
return 0;
|
||||||
return result.release();
|
return result.release();
|
||||||
@ -437,7 +439,9 @@ Archive::loadSymbolTable(std::string* ErrorMsg) {
|
|||||||
// Open the archive and load just the symbol tables
|
// Open the archive and load just the symbol tables
|
||||||
Archive*
|
Archive*
|
||||||
Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) {
|
Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) {
|
||||||
std::auto_ptr<Archive> result ( new Archive(file, true) );
|
std::auto_ptr<Archive> result ( new Archive(file) );
|
||||||
|
if (result->mapToMemory(ErrorMessage))
|
||||||
|
return 0;
|
||||||
if (!result->loadSymbolTable(ErrorMessage))
|
if (!result->loadSymbolTable(ErrorMessage))
|
||||||
return 0;
|
return 0;
|
||||||
return result.release();
|
return result.release();
|
||||||
|
@ -64,7 +64,7 @@ inline unsigned numVbrBytes(unsigned num) {
|
|||||||
// Create an empty archive.
|
// Create an empty archive.
|
||||||
Archive*
|
Archive*
|
||||||
Archive::CreateEmpty(const sys::Path& FilePath ) {
|
Archive::CreateEmpty(const sys::Path& FilePath ) {
|
||||||
Archive* result = new Archive(FilePath,false);
|
Archive* result = new Archive(FilePath);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,17 +151,17 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
|
|||||||
|
|
||||||
// Insert a file into the archive before some other member. This also takes care
|
// Insert a file into the archive before some other member. This also takes care
|
||||||
// of extracting the necessary flags and information from the file.
|
// of extracting the necessary flags and information from the file.
|
||||||
void
|
bool
|
||||||
Archive::addFileBefore(const sys::Path& filePath, iterator where) {
|
Archive::addFileBefore(const sys::Path& filePath, iterator where,
|
||||||
|
std::string* ErrMsg) {
|
||||||
assert(filePath.exists() && "Can't add a non-existent file");
|
assert(filePath.exists() && "Can't add a non-existent file");
|
||||||
|
|
||||||
ArchiveMember* mbr = new ArchiveMember(this);
|
ArchiveMember* mbr = new ArchiveMember(this);
|
||||||
|
|
||||||
mbr->data = 0;
|
mbr->data = 0;
|
||||||
mbr->path = filePath;
|
mbr->path = filePath;
|
||||||
std::string err;
|
if (mbr->path.getFileStatus(mbr->info, ErrMsg))
|
||||||
if (mbr->path.getFileStatus(mbr->info, &err))
|
return true;
|
||||||
throw err;
|
|
||||||
|
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
bool hasSlash = filePath.toString().find('/') != std::string::npos;
|
bool hasSlash = filePath.toString().find('/') != std::string::npos;
|
||||||
@ -183,6 +183,7 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where) {
|
|||||||
}
|
}
|
||||||
mbr->flags = flags;
|
mbr->flags = flags;
|
||||||
members.insert(where,mbr);
|
members.insert(where,mbr);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write one member out to the file.
|
// Write one member out to the file.
|
||||||
@ -193,7 +194,7 @@ Archive::writeMember(
|
|||||||
bool CreateSymbolTable,
|
bool CreateSymbolTable,
|
||||||
bool TruncateNames,
|
bool TruncateNames,
|
||||||
bool ShouldCompress,
|
bool ShouldCompress,
|
||||||
std::string* error
|
std::string* ErrMsg
|
||||||
) {
|
) {
|
||||||
|
|
||||||
unsigned filepos = ARFile.tellp();
|
unsigned filepos = ARFile.tellp();
|
||||||
@ -205,12 +206,11 @@ Archive::writeMember(
|
|||||||
const char* data = (const char*)member.getData();
|
const char* data = (const char*)member.getData();
|
||||||
sys::MappedFile* mFile = 0;
|
sys::MappedFile* mFile = 0;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
std::string ErrMsg;
|
|
||||||
mFile = new sys::MappedFile();
|
mFile = new sys::MappedFile();
|
||||||
if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, &ErrMsg))
|
if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
if (!(data = (const char*) mFile->map(&ErrMsg)))
|
if (!(data = (const char*) mFile->map(ErrMsg)))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
fSize = mFile->size();
|
fSize = mFile->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,8 +246,9 @@ Archive::writeMember(
|
|||||||
mFile->close();
|
mFile->close();
|
||||||
delete mFile;
|
delete mFile;
|
||||||
}
|
}
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Can't parse bytecode member: " + member.getPath().toString();
|
*ErrMsg = "Can't parse bytecode member: " + member.getPath().toString();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,9 +275,9 @@ Archive::writeMember(
|
|||||||
data +=4;
|
data +=4;
|
||||||
fSize -= 4;
|
fSize -= 4;
|
||||||
}
|
}
|
||||||
fSize = Compressor::compressToNewBuffer(data,fSize,output,error);
|
fSize = Compressor::compressToNewBuffer(data,fSize,output,ErrMsg);
|
||||||
if (fSize == 0)
|
if (fSize == 0)
|
||||||
return false;
|
return true;
|
||||||
data = output;
|
data = output;
|
||||||
if (member.isBytecode())
|
if (member.isBytecode())
|
||||||
hdrSize = -fSize-4;
|
hdrSize = -fSize-4;
|
||||||
@ -320,7 +321,7 @@ Archive::writeMember(
|
|||||||
mFile->close();
|
mFile->close();
|
||||||
delete mFile;
|
delete mFile;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out the LLVM symbol table as an archive member to the file.
|
// Write out the LLVM symbol table as an archive member to the file.
|
||||||
@ -380,7 +381,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) {
|
|||||||
// compressing each archive member.
|
// compressing each archive member.
|
||||||
bool
|
bool
|
||||||
Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
||||||
std::string* error)
|
std::string* ErrMsg)
|
||||||
{
|
{
|
||||||
// Make sure they haven't opened up the file, not loaded it,
|
// Make sure they haven't opened up the file, not loaded it,
|
||||||
// but are now trying to write it which would wipe out the file.
|
// but are now trying to write it which would wipe out the file.
|
||||||
@ -389,8 +390,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
|
|
||||||
// Create a temporary file to store the archive in
|
// Create a temporary file to store the archive in
|
||||||
sys::Path TmpArchive = archPath;
|
sys::Path TmpArchive = archPath;
|
||||||
if (TmpArchive.createTemporaryFileOnDisk(error))
|
if (TmpArchive.createTemporaryFileOnDisk(ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
// Make sure the temporary gets removed if we crash
|
// Make sure the temporary gets removed if we crash
|
||||||
sys::RemoveFileOnSignal(TmpArchive);
|
sys::RemoveFileOnSignal(TmpArchive);
|
||||||
@ -404,9 +405,9 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
|
if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Error opening archive file: " + archPath.toString();
|
*ErrMsg = "Error opening archive file: " + archPath.toString();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're creating a symbol table, reset it now
|
// If we're creating a symbol table, reset it now
|
||||||
@ -421,12 +422,12 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// Loop over all member files, and write them out. Note that this also
|
// Loop over all member files, and write them out. Note that this also
|
||||||
// builds the symbol table, symTab.
|
// builds the symbol table, symTab.
|
||||||
for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
|
for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
|
||||||
if (!writeMember(*I, ArchiveFile, CreateSymbolTable,
|
if (writeMember(*I, ArchiveFile, CreateSymbolTable,
|
||||||
TruncateNames, Compress, error)) {
|
TruncateNames, Compress, ErrMsg)) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
ArchiveFile.close();
|
ArchiveFile.close();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,27 +444,26 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
|
|
||||||
// Map in the archive we just wrote.
|
// Map in the archive we just wrote.
|
||||||
sys::MappedFile arch;
|
sys::MappedFile arch;
|
||||||
std::string ErrMsg;
|
if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, &ErrMsg))
|
return true;
|
||||||
throw ErrMsg;
|
|
||||||
const char* base;
|
const char* base;
|
||||||
if (!(base = (const char*) arch.map(&ErrMsg)))
|
if (!(base = (const char*) arch.map(ErrMsg)))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
|
|
||||||
// Open another temporary file in order to avoid invalidating the
|
// Open another temporary file in order to avoid invalidating the
|
||||||
// mmapped data
|
// mmapped data
|
||||||
sys::Path FinalFilePath = archPath;
|
sys::Path FinalFilePath = archPath;
|
||||||
if (FinalFilePath.createTemporaryFileOnDisk(error))
|
if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
sys::RemoveFileOnSignal(FinalFilePath);
|
sys::RemoveFileOnSignal(FinalFilePath);
|
||||||
|
|
||||||
std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
|
std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
|
||||||
if (!FinalFile.is_open() || FinalFile.bad()) {
|
if (!FinalFile.is_open() || FinalFile.bad()) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Error opening archive file: " + FinalFilePath.toString();
|
*ErrMsg = "Error opening archive file: " + FinalFilePath.toString();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the file magic number
|
// Write the file magic number
|
||||||
@ -475,11 +475,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// compatibility with other ar(1) implementations as well as allowing the
|
// compatibility with other ar(1) implementations as well as allowing the
|
||||||
// archive to store both native .o and LLVM .bc files, both indexed.
|
// archive to store both native .o and LLVM .bc files, both indexed.
|
||||||
if (foreignST) {
|
if (foreignST) {
|
||||||
if (!writeMember(*foreignST, FinalFile, false, false, false, error)) {
|
if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) {
|
||||||
FinalFile.close();
|
FinalFile.close();
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,8 +496,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
arch.close();
|
arch.close();
|
||||||
|
|
||||||
// Move the final file over top of TmpArchive
|
// Move the final file over top of TmpArchive
|
||||||
if (FinalFilePath.renamePathOnDisk(TmpArchive, error))
|
if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before we replace the actual archive, we need to forget all the
|
// Before we replace the actual archive, we need to forget all the
|
||||||
@ -505,8 +505,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// this because we cannot replace an open file on Windows.
|
// this because we cannot replace an open file on Windows.
|
||||||
cleanUpMemory();
|
cleanUpMemory();
|
||||||
|
|
||||||
if (TmpArchive.renamePathOnDisk(archPath, error))
|
if (TmpArchive.renamePathOnDisk(archPath, ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ ArchiveMember::ArchiveMember(Archive* PAR)
|
|||||||
// This method allows an ArchiveMember to be replaced with the data for a
|
// This method allows an ArchiveMember to be replaced with the data for a
|
||||||
// different file, presumably as an update to the member. It also makes sure
|
// different file, presumably as an update to the member. It also makes sure
|
||||||
// the flags are reset correctly.
|
// the flags are reset correctly.
|
||||||
void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
|
||||||
assert(newFile.exists() && "Can't replace with a non-existent file");
|
assert(newFile.exists() && "Can't replace with a non-existent file");
|
||||||
data = 0;
|
data = 0;
|
||||||
path = newFile;
|
path = newFile;
|
||||||
@ -110,8 +110,8 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
|||||||
path.getMagicNumber(magic,4);
|
path.getMagicNumber(magic,4);
|
||||||
signature = magic.c_str();
|
signature = magic.c_str();
|
||||||
std::string err;
|
std::string err;
|
||||||
if (path.getFileStatus(info, &err))
|
if (path.getFileStatus(info, ErrMsg))
|
||||||
throw err;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine what kind of file it is
|
// Determine what kind of file it is
|
||||||
@ -127,23 +127,27 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
|
|||||||
flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
|
flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archive constructor - this is the only constructor that gets used for the
|
// Archive constructor - this is the only constructor that gets used for the
|
||||||
// Archive class. Everything else (default,copy) is deprecated. This just
|
// Archive class. Everything else (default,copy) is deprecated. This just
|
||||||
// initializes and maps the file into memory, if requested.
|
// initializes and maps the file into memory, if requested.
|
||||||
Archive::Archive(const sys::Path& filename, bool map )
|
Archive::Archive(const sys::Path& filename)
|
||||||
: archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
|
: archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
|
||||||
symTabSize(0), firstFileOffset(0), modules(), foreignST(0)
|
symTabSize(0), firstFileOffset(0), modules(), foreignST(0)
|
||||||
{
|
{
|
||||||
if (map) {
|
}
|
||||||
std::string ErrMsg;
|
|
||||||
mapfile = new sys::MappedFile();
|
bool
|
||||||
if (mapfile->open(filename, sys::MappedFile::READ_ACCESS, &ErrMsg))
|
Archive::mapToMemory(std::string* ErrMsg)
|
||||||
throw ErrMsg;
|
{
|
||||||
if (!(base = (char*) mapfile->map(&ErrMsg)))
|
mapfile = new sys::MappedFile();
|
||||||
throw ErrMsg;
|
if (mapfile->open(archPath, sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
}
|
return true;
|
||||||
|
if (!(base = (char*) mapfile->map(ErrMsg)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Archive::cleanUpMemory() {
|
void Archive::cleanUpMemory() {
|
||||||
|
@ -330,7 +330,9 @@ Archive::loadArchive(std::string* error) {
|
|||||||
Archive*
|
Archive*
|
||||||
Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
Archive::OpenAndLoad(const sys::Path& file, std::string* ErrorMessage)
|
||||||
{
|
{
|
||||||
std::auto_ptr<Archive> result ( new Archive(file, true));
|
std::auto_ptr<Archive> result ( new Archive(file));
|
||||||
|
if (result->mapToMemory(ErrorMessage))
|
||||||
|
return 0;
|
||||||
if (!result->loadArchive(ErrorMessage))
|
if (!result->loadArchive(ErrorMessage))
|
||||||
return 0;
|
return 0;
|
||||||
return result.release();
|
return result.release();
|
||||||
@ -437,7 +439,9 @@ Archive::loadSymbolTable(std::string* ErrorMsg) {
|
|||||||
// Open the archive and load just the symbol tables
|
// Open the archive and load just the symbol tables
|
||||||
Archive*
|
Archive*
|
||||||
Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) {
|
Archive::OpenAndLoadSymbols(const sys::Path& file, std::string* ErrorMessage) {
|
||||||
std::auto_ptr<Archive> result ( new Archive(file, true) );
|
std::auto_ptr<Archive> result ( new Archive(file) );
|
||||||
|
if (result->mapToMemory(ErrorMessage))
|
||||||
|
return 0;
|
||||||
if (!result->loadSymbolTable(ErrorMessage))
|
if (!result->loadSymbolTable(ErrorMessage))
|
||||||
return 0;
|
return 0;
|
||||||
return result.release();
|
return result.release();
|
||||||
|
@ -64,7 +64,7 @@ inline unsigned numVbrBytes(unsigned num) {
|
|||||||
// Create an empty archive.
|
// Create an empty archive.
|
||||||
Archive*
|
Archive*
|
||||||
Archive::CreateEmpty(const sys::Path& FilePath ) {
|
Archive::CreateEmpty(const sys::Path& FilePath ) {
|
||||||
Archive* result = new Archive(FilePath,false);
|
Archive* result = new Archive(FilePath);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,17 +151,17 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
|
|||||||
|
|
||||||
// Insert a file into the archive before some other member. This also takes care
|
// Insert a file into the archive before some other member. This also takes care
|
||||||
// of extracting the necessary flags and information from the file.
|
// of extracting the necessary flags and information from the file.
|
||||||
void
|
bool
|
||||||
Archive::addFileBefore(const sys::Path& filePath, iterator where) {
|
Archive::addFileBefore(const sys::Path& filePath, iterator where,
|
||||||
|
std::string* ErrMsg) {
|
||||||
assert(filePath.exists() && "Can't add a non-existent file");
|
assert(filePath.exists() && "Can't add a non-existent file");
|
||||||
|
|
||||||
ArchiveMember* mbr = new ArchiveMember(this);
|
ArchiveMember* mbr = new ArchiveMember(this);
|
||||||
|
|
||||||
mbr->data = 0;
|
mbr->data = 0;
|
||||||
mbr->path = filePath;
|
mbr->path = filePath;
|
||||||
std::string err;
|
if (mbr->path.getFileStatus(mbr->info, ErrMsg))
|
||||||
if (mbr->path.getFileStatus(mbr->info, &err))
|
return true;
|
||||||
throw err;
|
|
||||||
|
|
||||||
unsigned flags = 0;
|
unsigned flags = 0;
|
||||||
bool hasSlash = filePath.toString().find('/') != std::string::npos;
|
bool hasSlash = filePath.toString().find('/') != std::string::npos;
|
||||||
@ -183,6 +183,7 @@ Archive::addFileBefore(const sys::Path& filePath, iterator where) {
|
|||||||
}
|
}
|
||||||
mbr->flags = flags;
|
mbr->flags = flags;
|
||||||
members.insert(where,mbr);
|
members.insert(where,mbr);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write one member out to the file.
|
// Write one member out to the file.
|
||||||
@ -193,7 +194,7 @@ Archive::writeMember(
|
|||||||
bool CreateSymbolTable,
|
bool CreateSymbolTable,
|
||||||
bool TruncateNames,
|
bool TruncateNames,
|
||||||
bool ShouldCompress,
|
bool ShouldCompress,
|
||||||
std::string* error
|
std::string* ErrMsg
|
||||||
) {
|
) {
|
||||||
|
|
||||||
unsigned filepos = ARFile.tellp();
|
unsigned filepos = ARFile.tellp();
|
||||||
@ -205,12 +206,11 @@ Archive::writeMember(
|
|||||||
const char* data = (const char*)member.getData();
|
const char* data = (const char*)member.getData();
|
||||||
sys::MappedFile* mFile = 0;
|
sys::MappedFile* mFile = 0;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
std::string ErrMsg;
|
|
||||||
mFile = new sys::MappedFile();
|
mFile = new sys::MappedFile();
|
||||||
if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, &ErrMsg))
|
if (mFile->open(member.getPath(), sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
if (!(data = (const char*) mFile->map(&ErrMsg)))
|
if (!(data = (const char*) mFile->map(ErrMsg)))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
fSize = mFile->size();
|
fSize = mFile->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,8 +246,9 @@ Archive::writeMember(
|
|||||||
mFile->close();
|
mFile->close();
|
||||||
delete mFile;
|
delete mFile;
|
||||||
}
|
}
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Can't parse bytecode member: " + member.getPath().toString();
|
*ErrMsg = "Can't parse bytecode member: " + member.getPath().toString();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,9 +275,9 @@ Archive::writeMember(
|
|||||||
data +=4;
|
data +=4;
|
||||||
fSize -= 4;
|
fSize -= 4;
|
||||||
}
|
}
|
||||||
fSize = Compressor::compressToNewBuffer(data,fSize,output,error);
|
fSize = Compressor::compressToNewBuffer(data,fSize,output,ErrMsg);
|
||||||
if (fSize == 0)
|
if (fSize == 0)
|
||||||
return false;
|
return true;
|
||||||
data = output;
|
data = output;
|
||||||
if (member.isBytecode())
|
if (member.isBytecode())
|
||||||
hdrSize = -fSize-4;
|
hdrSize = -fSize-4;
|
||||||
@ -320,7 +321,7 @@ Archive::writeMember(
|
|||||||
mFile->close();
|
mFile->close();
|
||||||
delete mFile;
|
delete mFile;
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out the LLVM symbol table as an archive member to the file.
|
// Write out the LLVM symbol table as an archive member to the file.
|
||||||
@ -380,7 +381,7 @@ Archive::writeSymbolTable(std::ofstream& ARFile) {
|
|||||||
// compressing each archive member.
|
// compressing each archive member.
|
||||||
bool
|
bool
|
||||||
Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
||||||
std::string* error)
|
std::string* ErrMsg)
|
||||||
{
|
{
|
||||||
// Make sure they haven't opened up the file, not loaded it,
|
// Make sure they haven't opened up the file, not loaded it,
|
||||||
// but are now trying to write it which would wipe out the file.
|
// but are now trying to write it which would wipe out the file.
|
||||||
@ -389,8 +390,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
|
|
||||||
// Create a temporary file to store the archive in
|
// Create a temporary file to store the archive in
|
||||||
sys::Path TmpArchive = archPath;
|
sys::Path TmpArchive = archPath;
|
||||||
if (TmpArchive.createTemporaryFileOnDisk(error))
|
if (TmpArchive.createTemporaryFileOnDisk(ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
// Make sure the temporary gets removed if we crash
|
// Make sure the temporary gets removed if we crash
|
||||||
sys::RemoveFileOnSignal(TmpArchive);
|
sys::RemoveFileOnSignal(TmpArchive);
|
||||||
@ -404,9 +405,9 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
|
if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Error opening archive file: " + archPath.toString();
|
*ErrMsg = "Error opening archive file: " + archPath.toString();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're creating a symbol table, reset it now
|
// If we're creating a symbol table, reset it now
|
||||||
@ -421,12 +422,12 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// Loop over all member files, and write them out. Note that this also
|
// Loop over all member files, and write them out. Note that this also
|
||||||
// builds the symbol table, symTab.
|
// builds the symbol table, symTab.
|
||||||
for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
|
for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
|
||||||
if (!writeMember(*I, ArchiveFile, CreateSymbolTable,
|
if (writeMember(*I, ArchiveFile, CreateSymbolTable,
|
||||||
TruncateNames, Compress, error)) {
|
TruncateNames, Compress, ErrMsg)) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
ArchiveFile.close();
|
ArchiveFile.close();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,27 +444,26 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
|
|
||||||
// Map in the archive we just wrote.
|
// Map in the archive we just wrote.
|
||||||
sys::MappedFile arch;
|
sys::MappedFile arch;
|
||||||
std::string ErrMsg;
|
if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, ErrMsg))
|
||||||
if (arch.open(TmpArchive, sys::MappedFile::READ_ACCESS, &ErrMsg))
|
return true;
|
||||||
throw ErrMsg;
|
|
||||||
const char* base;
|
const char* base;
|
||||||
if (!(base = (const char*) arch.map(&ErrMsg)))
|
if (!(base = (const char*) arch.map(ErrMsg)))
|
||||||
throw ErrMsg;
|
return true;
|
||||||
|
|
||||||
// Open another temporary file in order to avoid invalidating the
|
// Open another temporary file in order to avoid invalidating the
|
||||||
// mmapped data
|
// mmapped data
|
||||||
sys::Path FinalFilePath = archPath;
|
sys::Path FinalFilePath = archPath;
|
||||||
if (FinalFilePath.createTemporaryFileOnDisk(error))
|
if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
sys::RemoveFileOnSignal(FinalFilePath);
|
sys::RemoveFileOnSignal(FinalFilePath);
|
||||||
|
|
||||||
std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
|
std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
|
||||||
if (!FinalFile.is_open() || FinalFile.bad()) {
|
if (!FinalFile.is_open() || FinalFile.bad()) {
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
if (error)
|
if (ErrMsg)
|
||||||
*error = "Error opening archive file: " + FinalFilePath.toString();
|
*ErrMsg = "Error opening archive file: " + FinalFilePath.toString();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the file magic number
|
// Write the file magic number
|
||||||
@ -475,11 +475,11 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// compatibility with other ar(1) implementations as well as allowing the
|
// compatibility with other ar(1) implementations as well as allowing the
|
||||||
// archive to store both native .o and LLVM .bc files, both indexed.
|
// archive to store both native .o and LLVM .bc files, both indexed.
|
||||||
if (foreignST) {
|
if (foreignST) {
|
||||||
if (!writeMember(*foreignST, FinalFile, false, false, false, error)) {
|
if (writeMember(*foreignST, FinalFile, false, false, false, ErrMsg)) {
|
||||||
FinalFile.close();
|
FinalFile.close();
|
||||||
if (TmpArchive.exists())
|
if (TmpArchive.exists())
|
||||||
TmpArchive.eraseFromDisk();
|
TmpArchive.eraseFromDisk();
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,8 +496,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
arch.close();
|
arch.close();
|
||||||
|
|
||||||
// Move the final file over top of TmpArchive
|
// Move the final file over top of TmpArchive
|
||||||
if (FinalFilePath.renamePathOnDisk(TmpArchive, error))
|
if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Before we replace the actual archive, we need to forget all the
|
// Before we replace the actual archive, we need to forget all the
|
||||||
@ -505,8 +505,8 @@ Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames, bool Compress,
|
|||||||
// this because we cannot replace an open file on Windows.
|
// this because we cannot replace an open file on Windows.
|
||||||
cleanUpMemory();
|
cleanUpMemory();
|
||||||
|
|
||||||
if (TmpArchive.renamePathOnDisk(archPath, error))
|
if (TmpArchive.renamePathOnDisk(archPath, ErrMsg))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -586,7 +586,8 @@ doQuickAppend(std::string* ErrMsg) {
|
|||||||
// Append them quickly.
|
// Append them quickly.
|
||||||
for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
|
for (std::set<sys::Path>::iterator PI = Paths.begin(), PE = Paths.end();
|
||||||
PI != PE; ++PI) {
|
PI != PE; ++PI) {
|
||||||
TheArchive->addFileBefore(*PI,TheArchive->end());
|
if (TheArchive->addFileBefore(*PI,TheArchive->end(),ErrMsg))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're done editting, reconstruct the archive.
|
// We're done editting, reconstruct the archive.
|
||||||
@ -647,15 +648,17 @@ doReplaceOrInsert(std::string* ErrMsg) {
|
|||||||
sys::FileStatus si;
|
sys::FileStatus si;
|
||||||
std::string Err;
|
std::string Err;
|
||||||
if (found->getFileStatus(si, &Err))
|
if (found->getFileStatus(si, &Err))
|
||||||
throw Err;
|
return true;
|
||||||
if (si.isDir) {
|
if (si.isDir) {
|
||||||
if (OnlyUpdate) {
|
if (OnlyUpdate) {
|
||||||
// Replace the item only if it is newer.
|
// Replace the item only if it is newer.
|
||||||
if (si.modTime > I->getModTime())
|
if (si.modTime > I->getModTime())
|
||||||
I->replaceWith(*found);
|
if (I->replaceWith(*found, ErrMsg))
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// Replace the item regardless of time stamp
|
// Replace the item regardless of time stamp
|
||||||
I->replaceWith(*found);
|
if (I->replaceWith(*found, ErrMsg))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We purposefully ignore directories.
|
// We purposefully ignore directories.
|
||||||
@ -679,7 +682,8 @@ doReplaceOrInsert(std::string* ErrMsg) {
|
|||||||
if (!remaining.empty()) {
|
if (!remaining.empty()) {
|
||||||
for (std::set<sys::Path>::iterator PI = remaining.begin(),
|
for (std::set<sys::Path>::iterator PI = remaining.begin(),
|
||||||
PE = remaining.end(); PI != PE; ++PI) {
|
PE = remaining.end(); PI != PE; ++PI) {
|
||||||
TheArchive->addFileBefore(*PI,insert_spot);
|
if (TheArchive->addFileBefore(*PI,insert_spot, ErrMsg))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user