14cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner//===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===// 24cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// 34cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// The LLVM Compiler Infrastructure 44cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// 57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source 67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details. 74cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// 84cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner//===----------------------------------------------------------------------===// 94cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// 104cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// This header file declares the Archive and ArchiveMember classes that provide 114cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// manipulation of LLVM Archive files. The implementation is provided by the 124cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// lib/Bitcode/Archive library. This library is used to read and write 134cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// archive (*.a) files that contain LLVM bitcode files (or others). 144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// 154cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner//===----------------------------------------------------------------------===// 164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 17a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif#ifndef LLVM_BITCODE_ARCHIVE_H 18a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif#define LLVM_BITCODE_ARCHIVE_H 194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2043d1fd449f1a0ac9d9dafa0b9569bb6b2e976198Anton Korobeynikov#include "llvm/ADT/ilist.h" 21fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohman#include "llvm/ADT/ilist_node.h" 221f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h" 234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner#include <map> 244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner#include <set> 254cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattnernamespace llvm { 277f6b4479044e7f6553f517737caa18e4e543697cChris Lattner class MemoryBuffer; 284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner// Forward declare classes 304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattnerclass Module; // From VMCore 314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattnerclass Archive; // Declared below 324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattnerclass ArchiveMemberHeader; // Internal implementation class 3312ddd409535b52a7fa5157ded9a4cedd161fedb6Benjamin Kramerclass LLVMContext; // Global data 344cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 354cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// This class is the main class manipulated by users of the Archive class. It 364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// holds information about one member of the Archive. It is also the element 374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// stored by the Archive's ilist, the Archive's main abstraction. Because of 384cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// the special requirements of archive files, users are not permitted to 394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// construct ArchiveMember instances. You should obtain them from the methods 404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// of the Archive class instead. 414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// @brief This class represents a single archive member. 42fed90b6d097d50881afb45e4d79f430db66dd741Dan Gohmanclass ArchiveMember : public ilist_node<ArchiveMember> { 434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Types 444cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// These flags are used internally by the archive member to specify various 474cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// characteristics of the member. The various "is" methods below provide 484cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// access to the flags. The flags are not user settable. 494cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner enum Flags { 504cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner CompressedFlag = 1, ///< Member is a normal compressed file 514cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner SVR4SymbolTableFlag = 2, ///< Member is a SVR4 symbol table 524cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner BSD4SymbolTableFlag = 4, ///< Member is a BSD4 symbol table 534cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner LLVMSymbolTableFlag = 8, ///< Member is an LLVM symbol table 54db5565a1f549a979c84e559e18863f4c1d8f884fGabor Greif BitcodeFlag = 16, ///< Member is bitcode 554cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner HasPathFlag = 64, ///< Member has a full or partial path 564cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner HasLongFilenameFlag = 128, ///< Member uses the long filename syntax 574cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner StringTableFlag = 256 ///< Member is an ar(1) format string table 584cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner }; 594cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 604cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 614cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Accessors 624cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 634cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 644cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the parent Archive instance 654cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the archive associated with this member 664cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner Archive* getArchive() const { return parent; } 674cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 684cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the path to the Archive's file 694cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the path to the archive member 704cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::Path& getPath() const { return path; } 714cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 724cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// The "user" is the owner of the file per Unix security. This may not 734cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// have any applicability on non-Unix systems but is a required component 744cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// of the "ar" file format. 754cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the user associated with this archive member. 764cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned getUser() const { return info.getUser(); } 774cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 784cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// The "group" is the owning group of the file per Unix security. This 794cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// may not have any applicability on non-Unix systems but is a required 804cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// component of the "ar" file format. 814cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the group associated with this archive member. 824cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned getGroup() const { return info.getGroup(); } 834cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 844cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// The "mode" specifies the access permissions for the file per Unix 85a7a71a375c43cb802df6e5d55685ad5d4a17cf76Michael J. Spencer /// security. This may not have any applicability on non-Unix systems but is 864cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// a required component of the "ar" file format. 874cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the permission mode associated with this archive member. 884cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned getMode() const { return info.getMode(); } 894cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 904cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method returns the time at which the archive member was last 914cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// modified when it was not in the archive. 924cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the time of last modification of the archive member. 934cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner sys::TimeValue getModTime() const { return info.getTimestamp(); } 944cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 954cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the size of the archive member in bytes. 964cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the size of the archive member. 974cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner uint64_t getSize() const { return info.getSize(); } 984cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 994cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method returns the total size of the archive member as it 1004cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// appears on disk. This includes the file content, the header, the 1014cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// long file name if any, and the padding. 1024cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get total on-disk member size. 1034cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned getMemberSize() const; 1044cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1054cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method will return a pointer to the in-memory content of the 1064cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// archive member, if it is available. If the data has not been loaded 1074cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// into memory, the return value will be null. 1084cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns a pointer to the member's data. 1094cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the data content of the archive member 1109d44e702725a534c8e80edce52c7e71f71f37c06Benjamin Kramer const char* getData() const { return data; } 1114cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 112db5565a1f549a979c84e559e18863f4c1d8f884fGabor Greif /// This method determines if the member is a regular compressed file. 1134cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the archive member is a compressed regular file. 1144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if the member is a compressed regular file. 1154cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool isCompressed() const { return flags&CompressedFlag; } 1164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1174cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the member is a SVR4 (non-LLVM) symbol table 1184cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if this member is a SVR4 symbol table. 1194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; } 1204cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1214cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table 1224cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if this member is a BSD4.4 symbol table. 1234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; } 1244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1254cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the archive member is the LLVM symbol table 1264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if this member is the LLVM symbol table. 1274cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; } 1284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the archive member is the ar(1) string table 1304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if this member is the ar(1) string table. 1314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool isStringTable() const { return flags&StringTableFlag; } 1324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 133db5565a1f549a979c84e559e18863f4c1d8f884fGabor Greif /// @returns true iff the archive member is a bitcode file. 134db5565a1f549a979c84e559e18863f4c1d8f884fGabor Greif /// @brief Determine if this member is a bitcode file. 135e75ca3d809ff17260efa320a949cb91ea2b3981eGabor Greif bool isBitcode() const { return flags&BitcodeFlag; } 1364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the file name contains a path (directory) component. 1384cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Determine if the member has a path 1394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool hasPath() const { return flags&HasPathFlag; } 1404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// Long filenames are an artifact of the ar(1) file format which allows 1424cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// up to sixteen characters in its header and doesn't allow a path 1434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// separator character (/). To avoid this, a "long format" member name is 1444cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// allowed that doesn't have this restriction. This method determines if 1454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// that "long format" is used for this member. 1464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true iff the file name uses the long form 147a7a71a375c43cb802df6e5d55685ad5d4a17cf76Michael J. Spencer /// @brief Determine if the member has a long file name 1484cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool hasLongFilename() const { return flags&HasLongFilenameFlag; } 1494cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1504cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method returns the status info (like Unix stat(2)) for the archive 1514cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// member. The status info provides the file's size, permissions, and 1524cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// modification time. The contents of the Path::StatusInfo structure, other 1534cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// than the size and modification time, may not have utility on non-Unix 1544cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// systems. 1554cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the status info for the archive member 1564cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Obtain the status info for the archive member 1574cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::FileStatus &getFileStatus() const { return info; } 1584cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1594cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method causes the archive member to be replaced with the contents 1604cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// of the file specified by \p File. The contents of \p this will be 1614cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// updated to reflect the new data from \p File. The \p File must exist and 1624cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// be readable on entry to this method. 1634cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true if an error occurred, false otherwise 1644cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Replace contents of archive member with a new file. 1654cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool replaceWith(const sys::Path &aFile, std::string* ErrMsg); 1664cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1674cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 1684cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Data 1694cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 1704cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner private: 1714cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner Archive* parent; ///< Pointer to parent archive 1724cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner sys::PathWithStatus path; ///< Path of file containing the member 1734cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner sys::FileStatus info; ///< Status info (size,mode,date) 1744cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned flags; ///< Flags about the archive member 1759d44e702725a534c8e80edce52c7e71f71f37c06Benjamin Kramer const char* data; ///< Data for the member 1764cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1774cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 1784cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Constructors 1794cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 1804cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 1814cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// The default constructor is only used by the Archive's iplist when it 1824cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// constructs the list's sentry node. 1834cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ArchiveMember(); 1844cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1854cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner private: 1864cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// Used internally by the Archive class to construct an ArchiveMember. 1874cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// The contents of the ArchiveMember are filled out by the Archive class. 188cdf2b3b2f88d6f961b664e3f67a8ee37b46b0d27Dan Gohman explicit ArchiveMember(Archive *PAR); 1894cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1904cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner // So Archive can construct an ArchiveMember 1914cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner friend class llvm::Archive; 1924cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 1934cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner}; 1944cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 1954cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// This class defines the interface to LLVM Archive files. The Archive class 1964cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// presents the archive file as an ilist of ArchiveMember objects. The members 1974cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// can be rearranged in any fashion either by directly editing the ilist or by 1984cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// using editing methods on the Archive class (recommended). The Archive 1994cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// class also provides several ways of accessing the archive file for various 2004cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// purposes such as editing and linking. Full symbol table support is provided 2014cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// for loading only those files that resolve symbols. Note that read 2024cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// performance of this library is _crucial_ for performance of JIT type 2034cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// applications and the linkers. Consequently, the implementation of the class 2044cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner/// is optimized for reading. 2054cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattnerclass Archive { 206d3ff4a188e823baa141c288d31eb532ddf632b6eMisha Brukman 2074cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Types 2084cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 2094cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 2104cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This is the ilist type over which users may iterate to examine 2114cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the contents of the archive 2124cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief The ilist type of ArchiveMembers that Archive contains. 2134cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef iplist<ArchiveMember> MembersList; 2144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2154cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Forward mutable iterator over ArchiveMember 2164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef MembersList::iterator iterator; 2174cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2184cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Forward immutable iterator over ArchiveMember 2194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef MembersList::const_iterator const_iterator; 2204cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2214cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Reverse mutable iterator over ArchiveMember 2224cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef std::reverse_iterator<iterator> reverse_iterator; 2234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Reverse immutable iterator over ArchiveMember 2254cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 2264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2274cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief The in-memory version of the symbol table 2284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner typedef std::map<std::string,unsigned> SymTabType; 2294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 2314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name ilist accessor methods 2324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 2334cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 2344cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline iterator begin() { return members.begin(); } 2354cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const_iterator begin() const { return members.begin(); } 2364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline iterator end () { return members.end(); } 2374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const_iterator end () const { return members.end(); } 2384cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline reverse_iterator rbegin() { return members.rbegin(); } 2404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const_reverse_iterator rbegin() const { return members.rbegin(); } 2414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline reverse_iterator rend () { return members.rend(); } 2424cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const_reverse_iterator rend () const { return members.rend(); } 2434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 24434cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng inline size_t size() const { return members.size(); } 2454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline bool empty() const { return members.empty(); } 2464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const ArchiveMember& front() const { return members.front(); } 2474cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline ArchiveMember& front() { return members.front(); } 2484cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline const ArchiveMember& back() const { return members.back(); } 2494cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline ArchiveMember& back() { return members.back(); } 2504cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2514cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 2524cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name ilist mutator methods 2534cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 2544cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 2554cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method splices a \p src member from an archive (possibly \p this), 2564cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// to a position just before the member given by \p dest in \p this. When 2574cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the archive is written, \p src will be written in its new location. 2584cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Move a member to a new location 2594cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline void splice(iterator dest, Archive& arch, iterator src) 2604cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner { return members.splice(dest,arch.members,src); } 2614cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2624cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method erases a \p target member from the archive. When the 2634cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// archive is written, it will no longer contain \p target. The associated 2644cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// ArchiveMember is deleted. 2654cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Erase a member. 2664cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner inline iterator erase(iterator target) { return members.erase(target); } 2674cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2684cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 2694cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Constructors 2704cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 2714cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 2724cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// Create an empty archive file and associate it with the \p Filename. This 2734cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// method does not actually create the archive disk file. It creates an 2744cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// empty Archive object. If the writeToDisk method is called, the archive 2754cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// file \p Filename will be created at that point, with whatever content 2764cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the returned Archive object has at that time. 2774cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns An Archive* that represents the new archive file. 2784cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Create an empty Archive. 2794cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner static Archive* CreateEmpty( 2808b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson const sys::Path& Filename,///< Name of the archive to (eventually) create. 2814434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& C ///< Context to use for global information 2824cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 2834cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2844cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// Open an existing archive and load its contents in preparation for 2854cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// editing. After this call, the member ilist is completely populated based 2864cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// on the contents of the archive file. You should use this form of open if 2874cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// you intend to modify the archive or traverse its contents (e.g. for 2884cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// printing). 2894cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Open and load an archive file 2904cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner static Archive* OpenAndLoad( 2914cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::Path& filePath, ///< The file path to open and load 2924434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& C, ///< The context to use for global information 2934cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrorMessage ///< An optional error string 2944cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 2954cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 2964cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method opens an existing archive file from \p Filename and reads in 2974cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// its symbol table without reading in any of the archive's members. This 2984cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// reduces both I/O and cpu time in opening the archive if it is to be used 2994cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// solely for symbol lookup (e.g. during linking). The \p Filename must 300df782a789dea63016a941c4a44a7a6d6c8028608Dan Gohman /// exist and be an archive file or an error will be returned. This form 3014cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// of opening the archive is intended for read-only operations that need to 3024cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// locate members via the symbol table for link editing. Since the archve 3034cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// members are not read by this method, the archive will appear empty upon 3044cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// return. If editing operations are performed on the archive, they will 3054cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// completely replace the contents of the archive! It is recommended that 3064cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// if this form of opening the archive is used that only the symbol table 3074cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and 3084cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// findModulesDefiningSymbols) be used. 309df782a789dea63016a941c4a44a7a6d6c8028608Dan Gohman /// @returns an Archive* that represents the archive file, or null on error. 3104cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Open an existing archive and load its symbols. 3114cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner static Archive* OpenAndLoadSymbols( 3124cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::Path& Filename, ///< Name of the archive file to open 3134434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& C, ///< The context to use for global info 3144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrorMessage=0 ///< An optional error string 3154cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 3164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3174cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This destructor cleans up the Archive object, releases all memory, and 3184cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// closes files. It does nothing with the archive file on disk. If you 3194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// haven't used the writeToDisk method by the time the destructor is 3204cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// called, all changes to the archive will be lost. 3214cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Destruct in-memory archive 3224cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ~Archive(); 3234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 3254cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Accessors 3264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 3274cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 3284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the path to the archive file. 3294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the archive path. 3304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::Path& getPath() { return archPath; } 3314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method is provided so that editing methods can be invoked directly 3334cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// on the Archive's iplist of ArchiveMember. However, it is recommended 3344cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// that the usual STL style iterator interface be used instead. 3354cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the iplist of ArchiveMember 3364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the iplist of the members 3374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner MembersList& getMembers() { return members; } 3384cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method allows direct query of the Archive's symbol table. The 3404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// symbol table is a std::map of std::string (the symbol) to unsigned (the 3414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// file offset). Note that for efficiency reasons, the offset stored in 3424cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the symbol table is not the actual offset. It is the offset from the 3434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// beginning of the first "real" file member (after the symbol table). Use 3444cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the getFirstFileOffset() to obtain that offset and add this value to the 3454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// offset in the symbol table to obtain the real file offset. Note that 3464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// there is purposefully no interface provided by Archive to look up 3474cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// members by their offset. Use the findModulesDefiningSymbols and 3484cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// findModuleDefiningSymbol methods instead. 3494cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the Archive's symbol table. 3504cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the archive's symbol table 3514cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const SymTabType& getSymbolTable() { return symTab; } 3524cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3534cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method returns the offset in the archive file to the first "real" 3544cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// file member. Archive files, on disk, have a signature and might have a 3554cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// symbol table that precedes the first actual file member. This method 3564cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// allows you to determine what the size of those fields are. 3574cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns the offset to the first "real" file member in the archive. 3584cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Get the offset to the first "real" file member in the archive. 3594cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned getFirstFileOffset() { return firstFileOffset; } 3604cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 361a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// This method will scan the archive for bitcode modules, interpret them 3624cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// and return a vector of the instantiated modules in \p Modules. If an 3634cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// error occurs, this method will return true. If \p ErrMessage is not null 3644cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// and an error occurs, \p *ErrMessage will be set to a string explaining 3654cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// the error that occurred. 3664cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true if an error occurred 367a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// @brief Instantiate all the bitcode modules located in the archive 3684cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage); 3694cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3704cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This accessor looks up the \p symbol in the archive's symbol table and 3714cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// returns the associated module that defines that symbol. This method can 3724cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// be called as many times as necessary. This is handy for linking the 3734cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// archive into another module based on unresolved symbols. Note that the 374f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// Module returned by this accessor should not be deleted by the caller. It 375f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// is managed internally by the Archive class. It is possible that multiple 376f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// calls to this accessor will return the same Module instance because the 377f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// associated module defines multiple symbols. 378f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// @returns The Module* found or null if the archive does not contain a 379f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// module that defines the \p symbol. 3804cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Look up a module by symbol name. 381f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin Module* findModuleDefiningSymbol( 3824cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const std::string& symbol, ///< Symbol to be sought 3834cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrMessage ///< Error message storage, if non-zero 3844cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 3854cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 3864cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method is similar to findModuleDefiningSymbol but allows lookup of 3874cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// more than one symbol at a time. If \p symbols contains a list of 3884cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// undefined symbols in some module, then calling this method is like 3894cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// making one complete pass through the archive to resolve symbols but is 3904cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// more efficient than looking at the individual members. Note that on 3914cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// exit, the symbols resolved by this method will be removed from \p 3924cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// symbols to ensure they are not re-searched on a subsequent call. If 3934cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// you need to retain the list of symbols, make a copy. 3944cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Look up multiple symbols in the archive. 3954cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool findModulesDefiningSymbols( 3964cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::set<std::string>& symbols, ///< Symbols to be sought 397603d6b56a2b72358e7b599aab743beb44823d76cRafael Espindola SmallVectorImpl<Module*>& modules, ///< The modules matching \p symbols 3984cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrMessage ///< Error msg storage, if non-zero 3994cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 4004cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4014cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method determines whether the archive is a properly formed llvm 402a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// bitcode archive. It first makes sure the symbol table has been loaded 4034cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// and has a non-zero size. If it does, then it is an archive. If not, 404a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// then it tries to load all the bitcode modules of the archive. Finally, 405a7a71a375c43cb802df6e5d55685ad5d4a17cf76Michael J. Spencer /// it returns whether it was successful. 406a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// @returns true if the archive is a proper llvm bitcode archive 407a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// @brief Determine whether the archive is a proper llvm bitcode archive. 408a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif bool isBitcodeArchive(); 4094cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4104cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 4114cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Mutators 4124cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 4134cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner public: 4144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method is the only way to get the archive written to disk. It 4154cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// creates or overwrites the file specified when \p this was created 4164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// or opened. The arguments provide options for writing the archive. If 417a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// \p CreateSymbolTable is true, the archive is scanned for bitcode files 4184cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// and a symbol table of the externally visible function and global 4194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// variable names is created. If \p TruncateNames is true, the names of the 4204cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// archive members will have their path component stripped and the file 4214cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// name will be truncated at 15 characters. If \p Compress is specified, 4224cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// all archive members will be compressed before being written. If 4234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// \p PrintSymTab is true, the symbol table will be printed to std::cout. 4244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true if an error occurred, \p error set to error message 4254cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false if the writing succeeded. 4264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Write (possibly modified) archive contents to disk 4274cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool writeToDisk( 4284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool CreateSymbolTable=false, ///< Create Symbol table 4294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool TruncateNames=false, ///< Truncate the filename to 15 chars 4304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool Compress=false, ///< Compress files 4314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrMessage=0 ///< If non-null, where error msg is set 4324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 4334cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4344cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// This method adds a new file to the archive. The \p filename is examined 4354cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// to determine just enough information to create an ArchiveMember object 4364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// which is then inserted into the Archive object's ilist at the location 4374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// given by \p where. 4387a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner /// @returns true if an error occurred, false otherwise 4394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Add a file to the archive. 4404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool addFileBefore( 4414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const sys::Path& filename, ///< The file to be added 4424cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner iterator where, ///< Insertion point 4434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrMsg ///< Optional error message location 4444cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 4454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 4474cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Implementation 4484cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 4494cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner protected: 4504cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Construct an Archive for \p filename and optionally map it 4514cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// into memory. 4524434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson explicit Archive(const sys::Path& filename, LLVMContext& C); 4534cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 454181b6c9cb5def44658d15848e34c5c45d973f065Reid Spencer /// @param data The symbol table data to be parsed 455181b6c9cb5def44658d15848e34c5c45d973f065Reid Spencer /// @param len The length of the symbol table data 4564cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @param error Set to address of a std::string to get error messages 4574cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false on error 4584cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Parse the symbol table at \p data. 4594cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool parseSymbolTable(const void* data,unsigned len,std::string* error); 4604cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4614cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns A fully populated ArchiveMember or 0 if an error occurred. 4624cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Parse the header of a member starting at \p At 4634cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ArchiveMember* parseMemberHeader( 4644cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const char*&At, ///< The pointer to the location we're parsing 4654cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const char*End, ///< The pointer to the end of the archive 4664cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* error ///< Optional error message catcher 4674cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 4684cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 469181b6c9cb5def44658d15848e34c5c45d973f065Reid Spencer /// @param ErrMessage Set to address of a std::string to get error messages 4704cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false on error 4714cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Check that the archive signature is correct 4724cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool checkSignature(std::string* ErrMessage); 4734cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 474181b6c9cb5def44658d15848e34c5c45d973f065Reid Spencer /// @param ErrMessage Set to address of a std::string to get error messages 4754cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false on error 4764cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Load the entire archive. 4774cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool loadArchive(std::string* ErrMessage); 4784cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 479181b6c9cb5def44658d15848e34c5c45d973f065Reid Spencer /// @param ErrMessage Set to address of a std::string to get error messages 4804cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false on error 4814cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Load just the symbol table. 4824cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool loadSymbolTable(std::string* ErrMessage); 4834cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4844cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Write the symbol table to an ofstream. 485898fd7fd61c743c9b90ee5d0fa180b9ae1990d7bDan Gohman void writeSymbolTable(std::ofstream& ARFile); 4864cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 4874cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// Writes one ArchiveMember to an ofstream. If an error occurs, returns 488d3ff4a188e823baa141c288d31eb532ddf632b6eMisha Brukman /// false, otherwise true. If an error occurs and error is non-null then 4894cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// it will be set to an error message. 4904cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns false Writing member succeeded 4914cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @returns true Writing member failed, \p error set to error message 4924cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool writeMember( 4934cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const ArchiveMember& member, ///< The member to be written 494898fd7fd61c743c9b90ee5d0fa180b9ae1990d7bDan Gohman std::ofstream& ARFile, ///< The file to write member onto 4954cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool CreateSymbolTable, ///< Should symbol table be created? 4964cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool TruncateNames, ///< Should names be truncated to 11 chars? 4974cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool ShouldCompress, ///< Should the member be compressed? 4984cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string* ErrMessage ///< If non-null, place were error msg is set 4994cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ); 5004cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5014cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Fill in an ArchiveMemberHeader from ArchiveMember. 5024cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool fillHeader(const ArchiveMember&mbr, 5034cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const; 5044cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5054cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Maps archive into memory 5064cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner bool mapToMemory(std::string* ErrMsg); 5074cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5084cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Frees all the members and unmaps the archive file. 5094cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner void cleanUpMemory(); 5104cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 511a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif /// This type is used to keep track of bitcode modules loaded from the 5124cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// symbol table. It maps the file offset to a pair that consists of the 513f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin /// associated ArchiveMember and the Module. 5144cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @brief Module mapping type 515f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> > 5164cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ModuleMap; 5174cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5184cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5194cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 5204cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Data 5214cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 5224cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner protected: 5234cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner sys::Path archPath; ///< Path to the archive file we read/write 5244cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner MembersList members; ///< The ilist of ArchiveMember 5257f6b4479044e7f6553f517737caa18e4e543697cChris Lattner MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory 5264cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner const char* base; ///< Base of the memory mapped file data 5274cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner SymTabType symTab; ///< The symbol table 5284cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner std::string strtab; ///< The string table for long file names 5294cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned symTabSize; ///< Size in bytes of symbol table 5304cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner unsigned firstFileOffset; ///< Offset to first normal file. 5314cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ModuleMap modules; ///< The modules loaded via symbol lookup. 5324cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner ArchiveMember* foreignST; ///< This holds the foreign symbol table. 5334434ed44c45c87a72b7a0bf2f91211f895022b91Owen Anderson LLVMContext& Context; ///< This holds global data. 5344cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 5354cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @name Hidden 5364cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @{ 5374cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner private: 5384cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner Archive(); ///< Do not implement 5394cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner Archive(const Archive&); ///< Do not implement 5404cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner Archive& operator=(const Archive&); ///< Do not implement 5414cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner /// @} 5424cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner}; 5434cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5444cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner} // End llvm namespace 5454cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner 5464cbc5485e0ce158a81930fdf44b119ce7e129e13Chris Lattner#endif 547