diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2004-11-05 09:19:17 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2004-11-05 09:19:17 +0000 |
commit | ab19fa7967217f9dc988f5d607a500b318e85eb5 (patch) | |
tree | ec2fc2f5a7395b18e8d99d896980006d995c190c /include/llvm | |
parent | 53fe2beb01b82487d32e20e914ba246a071ec9e3 (diff) | |
download | external_llvm-ab19fa7967217f9dc988f5d607a500b318e85eb5.zip external_llvm-ab19fa7967217f9dc988f5d607a500b318e85eb5.tar.gz external_llvm-ab19fa7967217f9dc988f5d607a500b318e85eb5.tar.bz2 |
First version of the interface to Archive files. This introduces the
llvm::Archive class to provide for reading, writing, indexing and search
functions on standard ar(1) format files that contain bytecode modules.
Implementation to follow.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17487 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/Bytecode/Archive.h | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/include/llvm/Bytecode/Archive.h b/include/llvm/Bytecode/Archive.h new file mode 100644 index 0000000..66d49a1 --- /dev/null +++ b/include/llvm/Bytecode/Archive.h @@ -0,0 +1,261 @@ +//===-- llvm/Bytecode/Archive.h - LLVM Bytecode Archive ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header file defines the interface to LLVM Archive files. The interface +// is provided by the Archive class implemented by the lib/Bytecode/Archive +// library. This library is used to read and write archive (*.a) files that +// contain LLVM bytecode files (or others). It provides rudimentary capabilities +// to construct an archive file from a set of files, read the archive members +// into memory, search the archive for member files that fulfill unresolved +// symbols, and extract the archive back to the file system. Full +// symbol table support is provided for loading only those files that resolve +// symbols. Note that read performance of this library is _crucial_ for +// performance of JIT type applications and the linkers. Consequently, the +// library is optimized for reading. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BYTECODE_ARCHIVER_H +#define LLVM_BYTECODE_ARCHIVER_H + +#include "llvm/System/Path.h" +#include <map> + +namespace llvm { + +class ModuleProvider; +class Module; + +/// This class represents an archive file. It abstracts away the file format, +/// and logical operations that can be done on an archive file. It also provides +/// utilities for controlling the runtime loading/reading of the archive file +/// to provide efficient access mechanisms for JIT systems and linkers. +class Archive { + + /// @name Types + /// @{ + public: + /// The user's interface to the archive symbol table. This multimap allows + /// symbols to be looked up and modules to be instantiated from the file + /// lazily via the ModuleProvider::materializeModule method. + typedef std::map<std::string,ModuleProvider*> SymTab; + + /// This typedef is just shorthand for a vector of Path names + typedef std::vector<sys::Path> PathList; + + /// This typedef is just shorthand for a vector of Modules + typedef std::vector<Module*> ModuleList; + + /// This typedef is just shorthand for a vector of ModuleProvider + typedef std::vector<ModuleProvider*> ModuleProviderList; + + /// This typedef is just shorthand for a vector of strings + typedef std::vector<std::string> StringList; + + /// @} + /// @name Constructors + /// @{ + public: + /// Create an empty archive file, \p Filename. The returned Archive object + /// will have no file members and an empty symbol table. The actual archive + /// file is not created until either the flush() method is called or the + /// returned Archive object is destructed. + /// @throws std::string if an error occurs + /// @returns An Archive* that represents the new archive file. + /// @brief Create an empty archive file. + static Archive* CreateEmpty( + const sys::Path& Filename ///< Name of archive file + ); + + /// Create a new archive file, \p Filename, from the LLVM modules \p Modules. + /// The module's externally visible linkage symbols will be added to the + /// archive's symbol table. The names of the file members will be obtained + /// from the Module::getModuleId() method. If that name is not unique, it will + /// be made unique by appending a monotonically increasng integer to it. If + /// \p StripName is non-empty, it specifies a prefix to be stripped from the + /// name of the file members. This allows archives with relative path names + /// to be created. The actual archive file is not created until either the + /// flush() method is called or the returned Archive object is destructed. + /// @returns An Archive* that that represents the newly created archive file. + /// @throws std::string if an error occurs + /// @brief Create an archive file from modules. + static Archive* CreateFromModules( + const sys::Path& Filename, ///< Name of archive file + const ModuleList& Modules, ///< Modules to be put in archive + const std::string& StripName="" ///< Prefix to strip from member names + ); + + /// Create a new archive file, \p Filename, from a set of existing \p Files. + /// Each entry in \p Files will be added to the archive. If any file is an + /// llvm bytecode file, its externally visible linkage symbols will be added + /// to the archive's symbol table. If any of the paths in \p Files refer to + /// directories, those directories will be ignored. Full path names to + /// files must be provided. However, if \p StripName is non-empty, it + /// specifies a prefix string to be removed from each path before it is + /// written as the name of the file member. Any path names that do not have + /// the \p StripName as a prefix will be saved with the full path name + /// provided in \p Files. This permits archives relative to a top level + /// directory to be created. + /// @throws std::string if an error occurs + /// @brief Create an archive file from files. + static Archive* CreateFromFiles( + const sys::Path& Filename, ///< Name of archive file + const PathList& Files, ///< File paths to be put in archive + const std::string& StripName="" ///< Prefix path name to strip from names + ); + + /// Open an existing archive file from \p Filename. The necessary + /// arrangements to read the file are made, but nothing much is actually + /// read from the file. Use the Accessor methods below to lazily obtain + /// those portions of the file that are of interest. + /// @throws std::string if an error occurs + /// @brief Open an existing archive. + static Archive* Open( + const sys::Path& Filename ///< Name of the archive file + ); + + /// This destructor "finalizes" the archive. Regardless of whether the + /// archive was created or opened, all memory associated with the archive + /// is released, including any SymTab* returned by the getSymbolTable() + /// method, any ModuleProviders and their associated Modules returned by + /// any interface method, etc. Additionally, if the archive was created + /// using one of the Create* methods, the archive is written to disk in + /// its final format. After this method exits, none of the memory + /// associated with the archive is valid. It is the user's responsibility + /// to ensure that all references to such memory is removed before the + /// Archive is destructed. + /// @throws std::string if an error occurs + /// @brief Destruct in-memory archive + ~Archive(); + + /// @} + /// @name Accessors + /// @{ + public: + /// This accessor looks up the \p symbol in the archive's symbol table and + /// returns the associated module that defines that symbol. This method can + /// be called as many times as necessary. This is handy for linking the + /// archive into another module based on unresolved symbols. Note that the + /// ModuleProvider returned by this accessor is constant and it may refer + /// to the same ModuleProvider object returned by this accessor in a + /// previous call (because the associated module defines both symbols). To + /// use the returned ModuleProvider* you must make a copy and call the + /// materializeModule method on the copy. + /// @throws std::string if an error occurs + /// @returns The ModuleProvider* found or null if the archive does not + /// contain a module that defines the \p symbol. + /// @brief Look up a module by symbol name. + const ModuleProvider* findModuleContainingSymbol( + const std::string& symbol ///< Symbol to be sought + ) const; + + /// Return the list of all the paths for the file members in the archive. + /// This is handy for generating the table of contents of the archive. Note + /// that the PathList object is cleared before it is populated. Any previous + /// contents will be lost. + /// @throw std::string if an error occurs + /// @returns nothing + /// @brief Get all the paths in the archive + void getAllPaths( + PathList& Paths ///< The list of paths returned + ); + + /// This method returns a caller readable SymTab object which is a std::map + /// of symbol names to ModuleProviders. Callers can traverse this symbol + /// table, look up specific symbols, etc. and materialize any Modules they + /// want with the associated ModuleProviders. It is unnecessary to call + /// this accessor more than once as the same object is alway returned, even + /// if changes have been made. + /// @returns a constant SymTab* that is the same for every invocation. The + /// caller should not attempt to free or modify this SymTab object, just use + /// it. + /// @brief Get the archive's symbol table. + const SymTab* getSymbolTable(); + + /// Extract the contents of the archive back to the file system using \p + /// RootDir as the directory at the root of the extraction. Each file + /// member is written back as a separate file. If \p flat is false, then + /// directories are created as necessary to restore the files to the correct + /// sub-directory of \p root as specified in the full path of the file + /// member. Otherwise, paths are ignored and all file members will be + /// extracted to the \p root directory using only the filename portion of + /// the path (directories ignored). If \p symtab is true, the archive's + /// symbol table will also be extracted to a file named __SYMTAB. + /// @returns nothing + /// @throws std::string if an error occurs + /// @brief Extract archive contents to a file. + void extractAllToDirectory( + const sys::Path& RootDir, ///< The root directory for extraction + bool Flat = true, ///< false = recreate directory structure + bool Symtab = false ///< true = extract symbol table too + ); + + /// Extract one file in the archive back to the file system using \p RootDir + /// as the directory at the root of the extraction. The file \p name is + /// extracted and placed into \p RootDir. If \p Flat is false, then any + /// intermediate directory names in the file member's path will also be + /// created. Otherwise, the member's file is created in RootDir ignoring + /// the leading path and using only the member's file name. + /// @throws std::string if an error occurs. + /// @returns nothing + /// @brief Extract a single archive file. + void extractOneFileToDirectory( + const sys::Path& RootDir, ///< The root directory for extraction + const sys::Path& name, ///< Name of file to extract + bool Flat = true ///< false = recreate directories + ); + + /// @} + /// @name Mutators + /// @{ + public: + /// Each entry in \p Files will be added to the archive. If any file is an + /// llvm bytecode file, its externally visible linkage symbols will be added + /// to the archive's symbol table. If any of the paths in \p Files refer to + /// directories, those directories will be ignored. Full path names to + /// files must be provided. However, if \p StripName is non-empty, it + /// specifies a prefix string to be removed from each path before it is + /// written as the name of the file member. Any path names that do not have + /// the \p StripName as a prefix will be saved with the full path name + /// provided. This permits archives relative to a top level directory + /// to be created. + /// @throws std::string if an error occurs + /// @returns nothing + /// @brief Add a set of files to the archive. + void addFiles( + const PathList& Files, ///< The names of files to add to archive + const std::string& StripName="" ///< Prefix path to strip from names + ); + + /// Add a set of Modules to the archive. Names of member files will + /// be taken from the Module identifier (Module::getModuleIdentifier) if it + /// is unique. Non-unique member names will be made unique by appending a + /// number. The symbol table will be augmented with the global symbols of + /// all the modules provided. If \p StripName is non-empty, it + /// specifies a prefix string to be removed from each moduleId before it is + /// written as the name of the file member. Any path names that do not have + /// the \p StripName as a prefix will be saved with the full path name + /// provided. This permits archives relative to a top level directory to + /// be created. + /// @throws std::string if an error occurs + /// @returns nothing + /// @brief Add a set of modules to the archive. + void addModules( + const ModuleList& Modules, ///< The modules to add to the archive + const std::string& StripName="" ///< Prefix path to strip from names + ); + + + /// @} +}; + +} // End llvm namespace + +// vim: sw=2 ai +#endif |