Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

538 lines
26 KiB

  1. //===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This header file declares the Archive and ArchiveMember classes that provide
  11. // manipulation of LLVM Archive files. The implementation is provided by the
  12. // lib/Bitcode/Archive library. This library is used to read and write
  13. // archive (*.a) files that contain LLVM bitcode files (or others).
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #ifndef LLVM_BITCODE_ARCHIVE_H
  17. #define LLVM_BITCODE_ARCHIVE_H
  18. #include "llvm/ADT/ilist.h"
  19. #include "llvm/ADT/ilist_node.h"
  20. #include "llvm/Support/Path.h"
  21. #include <map>
  22. #include <set>
  23. namespace llvm {
  24. class MemoryBuffer;
  25. // Forward declare classes
  26. class Module; // From VMCore
  27. class Archive; // Declared below
  28. class ArchiveMemberHeader; // Internal implementation class
  29. class LLVMContext; // Global data
  30. /// This class is the main class manipulated by users of the Archive class. It
  31. /// holds information about one member of the Archive. It is also the element
  32. /// stored by the Archive's ilist, the Archive's main abstraction. Because of
  33. /// the special requirements of archive files, users are not permitted to
  34. /// construct ArchiveMember instances. You should obtain them from the methods
  35. /// of the Archive class instead.
  36. /// @brief This class represents a single archive member.
  37. class ArchiveMember : public ilist_node<ArchiveMember> {
  38. /// @name Types
  39. /// @{
  40. public:
  41. /// These flags are used internally by the archive member to specify various
  42. /// characteristics of the member. The various "is" methods below provide
  43. /// access to the flags. The flags are not user settable.
  44. enum Flags {
  45. SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
  46. BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
  47. LLVMSymbolTableFlag = 4, ///< Member is an LLVM symbol table
  48. BitcodeFlag = 8, ///< Member is bitcode
  49. HasPathFlag = 16, ///< Member has a full or partial path
  50. HasLongFilenameFlag = 32, ///< Member uses the long filename syntax
  51. StringTableFlag = 64 ///< Member is an ar(1) format string table
  52. };
  53. /// @}
  54. /// @name Accessors
  55. /// @{
  56. public:
  57. /// @returns the parent Archive instance
  58. /// @brief Get the archive associated with this member
  59. Archive* getArchive() const { return parent; }
  60. /// @returns the path to the Archive's file
  61. /// @brief Get the path to the archive member
  62. const sys::Path& getPath() const { return path; }
  63. /// The "user" is the owner of the file per Unix security. This may not
  64. /// have any applicability on non-Unix systems but is a required component
  65. /// of the "ar" file format.
  66. /// @brief Get the user associated with this archive member.
  67. unsigned getUser() const { return info.getUser(); }
  68. /// The "group" is the owning group of the file per Unix security. This
  69. /// may not have any applicability on non-Unix systems but is a required
  70. /// component of the "ar" file format.
  71. /// @brief Get the group associated with this archive member.
  72. unsigned getGroup() const { return info.getGroup(); }
  73. /// The "mode" specifies the access permissions for the file per Unix
  74. /// security. This may not have any applicability on non-Unix systems but is
  75. /// a required component of the "ar" file format.
  76. /// @brief Get the permission mode associated with this archive member.
  77. unsigned getMode() const { return info.getMode(); }
  78. /// This method returns the time at which the archive member was last
  79. /// modified when it was not in the archive.
  80. /// @brief Get the time of last modification of the archive member.
  81. sys::TimeValue getModTime() const { return info.getTimestamp(); }
  82. /// @returns the size of the archive member in bytes.
  83. /// @brief Get the size of the archive member.
  84. uint64_t getSize() const { return info.getSize(); }
  85. /// This method returns the total size of the archive member as it
  86. /// appears on disk. This includes the file content, the header, the
  87. /// long file name if any, and the padding.
  88. /// @brief Get total on-disk member size.
  89. unsigned getMemberSize() const;
  90. /// This method will return a pointer to the in-memory content of the
  91. /// archive member, if it is available. If the data has not been loaded
  92. /// into memory, the return value will be null.
  93. /// @returns a pointer to the member's data.
  94. /// @brief Get the data content of the archive member
  95. const char* getData() const { return data; }
  96. /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
  97. /// @brief Determine if this member is a SVR4 symbol table.
  98. bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
  99. /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
  100. /// @brief Determine if this member is a BSD4.4 symbol table.
  101. bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
  102. /// @returns true iff the archive member is the LLVM symbol table
  103. /// @brief Determine if this member is the LLVM symbol table.
  104. bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; }
  105. /// @returns true iff the archive member is the ar(1) string table
  106. /// @brief Determine if this member is the ar(1) string table.
  107. bool isStringTable() const { return flags&StringTableFlag; }
  108. /// @returns true iff the archive member is a bitcode file.
  109. /// @brief Determine if this member is a bitcode file.
  110. bool isBitcode() const { return flags&BitcodeFlag; }
  111. /// @returns true iff the file name contains a path (directory) component.
  112. /// @brief Determine if the member has a path
  113. bool hasPath() const { return flags&HasPathFlag; }
  114. /// Long filenames are an artifact of the ar(1) file format which allows
  115. /// up to sixteen characters in its header and doesn't allow a path
  116. /// separator character (/). To avoid this, a "long format" member name is
  117. /// allowed that doesn't have this restriction. This method determines if
  118. /// that "long format" is used for this member.
  119. /// @returns true iff the file name uses the long form
  120. /// @brief Determine if the member has a long file name
  121. bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
  122. /// This method returns the status info (like Unix stat(2)) for the archive
  123. /// member. The status info provides the file's size, permissions, and
  124. /// modification time. The contents of the Path::StatusInfo structure, other
  125. /// than the size and modification time, may not have utility on non-Unix
  126. /// systems.
  127. /// @returns the status info for the archive member
  128. /// @brief Obtain the status info for the archive member
  129. const sys::FileStatus &getFileStatus() const { return info; }
  130. /// This method causes the archive member to be replaced with the contents
  131. /// of the file specified by \p File. The contents of \p this will be
  132. /// updated to reflect the new data from \p File. The \p File must exist and
  133. /// be readable on entry to this method.
  134. /// @returns true if an error occurred, false otherwise
  135. /// @brief Replace contents of archive member with a new file.
  136. bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
  137. /// @}
  138. /// @name Data
  139. /// @{
  140. private:
  141. Archive* parent; ///< Pointer to parent archive
  142. sys::PathWithStatus path; ///< Path of file containing the member
  143. sys::FileStatus info; ///< Status info (size,mode,date)
  144. unsigned flags; ///< Flags about the archive member
  145. const char* data; ///< Data for the member
  146. /// @}
  147. /// @name Constructors
  148. /// @{
  149. public:
  150. /// The default constructor is only used by the Archive's iplist when it
  151. /// constructs the list's sentry node.
  152. ArchiveMember();
  153. private:
  154. /// Used internally by the Archive class to construct an ArchiveMember.
  155. /// The contents of the ArchiveMember are filled out by the Archive class.
  156. explicit ArchiveMember(Archive *PAR);
  157. // So Archive can construct an ArchiveMember
  158. friend class llvm::Archive;
  159. /// @}
  160. };
  161. /// This class defines the interface to LLVM Archive files. The Archive class
  162. /// presents the archive file as an ilist of ArchiveMember objects. The members
  163. /// can be rearranged in any fashion either by directly editing the ilist or by
  164. /// using editing methods on the Archive class (recommended). The Archive
  165. /// class also provides several ways of accessing the archive file for various
  166. /// purposes such as editing and linking. Full symbol table support is provided
  167. /// for loading only those files that resolve symbols. Note that read
  168. /// performance of this library is _crucial_ for performance of JIT type
  169. /// applications and the linkers. Consequently, the implementation of the class
  170. /// is optimized for reading.
  171. class Archive {
  172. /// @name Types
  173. /// @{
  174. public:
  175. /// This is the ilist type over which users may iterate to examine
  176. /// the contents of the archive
  177. /// @brief The ilist type of ArchiveMembers that Archive contains.
  178. typedef iplist<ArchiveMember> MembersList;
  179. /// @brief Forward mutable iterator over ArchiveMember
  180. typedef MembersList::iterator iterator;
  181. /// @brief Forward immutable iterator over ArchiveMember
  182. typedef MembersList::const_iterator const_iterator;
  183. /// @brief Reverse mutable iterator over ArchiveMember
  184. typedef std::reverse_iterator<iterator> reverse_iterator;
  185. /// @brief Reverse immutable iterator over ArchiveMember
  186. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  187. /// @brief The in-memory version of the symbol table
  188. typedef std::map<std::string,unsigned> SymTabType;
  189. /// @}
  190. /// @name ilist accessor methods
  191. /// @{
  192. public:
  193. inline iterator begin() { return members.begin(); }
  194. inline const_iterator begin() const { return members.begin(); }
  195. inline iterator end () { return members.end(); }
  196. inline const_iterator end () const { return members.end(); }
  197. inline reverse_iterator rbegin() { return members.rbegin(); }
  198. inline const_reverse_iterator rbegin() const { return members.rbegin(); }
  199. inline reverse_iterator rend () { return members.rend(); }
  200. inline const_reverse_iterator rend () const { return members.rend(); }
  201. inline size_t size() const { return members.size(); }
  202. inline bool empty() const { return members.empty(); }
  203. inline const ArchiveMember& front() const { return members.front(); }
  204. inline ArchiveMember& front() { return members.front(); }
  205. inline const ArchiveMember& back() const { return members.back(); }
  206. inline ArchiveMember& back() { return members.back(); }
  207. /// @}
  208. /// @name ilist mutator methods
  209. /// @{
  210. public:
  211. /// This method splices a \p src member from an archive (possibly \p this),
  212. /// to a position just before the member given by \p dest in \p this. When
  213. /// the archive is written, \p src will be written in its new location.
  214. /// @brief Move a member to a new location
  215. inline void splice(iterator dest, Archive& arch, iterator src)
  216. { return members.splice(dest,arch.members,src); }
  217. /// This method erases a \p target member from the archive. When the
  218. /// archive is written, it will no longer contain \p target. The associated
  219. /// ArchiveMember is deleted.
  220. /// @brief Erase a member.
  221. inline iterator erase(iterator target) { return members.erase(target); }
  222. /// @}
  223. /// @name Constructors
  224. /// @{
  225. public:
  226. /// Create an empty archive file and associate it with the \p Filename. This
  227. /// method does not actually create the archive disk file. It creates an
  228. /// empty Archive object. If the writeToDisk method is called, the archive
  229. /// file \p Filename will be created at that point, with whatever content
  230. /// the returned Archive object has at that time.
  231. /// @returns An Archive* that represents the new archive file.
  232. /// @brief Create an empty Archive.
  233. static Archive* CreateEmpty(
  234. const sys::Path& Filename,///< Name of the archive to (eventually) create.
  235. LLVMContext& C ///< Context to use for global information
  236. );
  237. /// Open an existing archive and load its contents in preparation for
  238. /// editing. After this call, the member ilist is completely populated based
  239. /// on the contents of the archive file. You should use this form of open if
  240. /// you intend to modify the archive or traverse its contents (e.g. for
  241. /// printing).
  242. /// @brief Open and load an archive file
  243. static Archive* OpenAndLoad(
  244. const sys::Path& filePath, ///< The file path to open and load
  245. LLVMContext& C, ///< The context to use for global information
  246. std::string* ErrorMessage ///< An optional error string
  247. );
  248. /// This method opens an existing archive file from \p Filename and reads in
  249. /// its symbol table without reading in any of the archive's members. This
  250. /// reduces both I/O and cpu time in opening the archive if it is to be used
  251. /// solely for symbol lookup (e.g. during linking). The \p Filename must
  252. /// exist and be an archive file or an error will be returned. This form
  253. /// of opening the archive is intended for read-only operations that need to
  254. /// locate members via the symbol table for link editing. Since the archve
  255. /// members are not read by this method, the archive will appear empty upon
  256. /// return. If editing operations are performed on the archive, they will
  257. /// completely replace the contents of the archive! It is recommended that
  258. /// if this form of opening the archive is used that only the symbol table
  259. /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
  260. /// findModulesDefiningSymbols) be used.
  261. /// @returns an Archive* that represents the archive file, or null on error.
  262. /// @brief Open an existing archive and load its symbols.
  263. static Archive* OpenAndLoadSymbols(
  264. const sys::Path& Filename, ///< Name of the archive file to open
  265. LLVMContext& C, ///< The context to use for global info
  266. std::string* ErrorMessage=0 ///< An optional error string
  267. );
  268. /// This destructor cleans up the Archive object, releases all memory, and
  269. /// closes files. It does nothing with the archive file on disk. If you
  270. /// haven't used the writeToDisk method by the time the destructor is
  271. /// called, all changes to the archive will be lost.
  272. /// @brief Destruct in-memory archive
  273. ~Archive();
  274. /// @}
  275. /// @name Accessors
  276. /// @{
  277. public:
  278. /// @returns the path to the archive file.
  279. /// @brief Get the archive path.
  280. const sys::Path& getPath() { return archPath; }
  281. /// This method is provided so that editing methods can be invoked directly
  282. /// on the Archive's iplist of ArchiveMember. However, it is recommended
  283. /// that the usual STL style iterator interface be used instead.
  284. /// @returns the iplist of ArchiveMember
  285. /// @brief Get the iplist of the members
  286. MembersList& getMembers() { return members; }
  287. /// This method allows direct query of the Archive's symbol table. The
  288. /// symbol table is a std::map of std::string (the symbol) to unsigned (the
  289. /// file offset). Note that for efficiency reasons, the offset stored in
  290. /// the symbol table is not the actual offset. It is the offset from the
  291. /// beginning of the first "real" file member (after the symbol table). Use
  292. /// the getFirstFileOffset() to obtain that offset and add this value to the
  293. /// offset in the symbol table to obtain the real file offset. Note that
  294. /// there is purposefully no interface provided by Archive to look up
  295. /// members by their offset. Use the findModulesDefiningSymbols and
  296. /// findModuleDefiningSymbol methods instead.
  297. /// @returns the Archive's symbol table.
  298. /// @brief Get the archive's symbol table
  299. const SymTabType& getSymbolTable() { return symTab; }
  300. /// This method returns the offset in the archive file to the first "real"
  301. /// file member. Archive files, on disk, have a signature and might have a
  302. /// symbol table that precedes the first actual file member. This method
  303. /// allows you to determine what the size of those fields are.
  304. /// @returns the offset to the first "real" file member in the archive.
  305. /// @brief Get the offset to the first "real" file member in the archive.
  306. unsigned getFirstFileOffset() { return firstFileOffset; }
  307. /// This method will scan the archive for bitcode modules, interpret them
  308. /// and return a vector of the instantiated modules in \p Modules. If an
  309. /// error occurs, this method will return true. If \p ErrMessage is not null
  310. /// and an error occurs, \p *ErrMessage will be set to a string explaining
  311. /// the error that occurred.
  312. /// @returns true if an error occurred
  313. /// @brief Instantiate all the bitcode modules located in the archive
  314. bool getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage);
  315. /// This accessor looks up the \p symbol in the archive's symbol table and
  316. /// returns the associated module that defines that symbol. This method can
  317. /// be called as many times as necessary. This is handy for linking the
  318. /// archive into another module based on unresolved symbols. Note that the
  319. /// Module returned by this accessor should not be deleted by the caller. It
  320. /// is managed internally by the Archive class. It is possible that multiple
  321. /// calls to this accessor will return the same Module instance because the
  322. /// associated module defines multiple symbols.
  323. /// @returns The Module* found or null if the archive does not contain a
  324. /// module that defines the \p symbol.
  325. /// @brief Look up a module by symbol name.
  326. Module* findModuleDefiningSymbol(
  327. const std::string& symbol, ///< Symbol to be sought
  328. std::string* ErrMessage ///< Error message storage, if non-zero
  329. );
  330. /// This method is similar to findModuleDefiningSymbol but allows lookup of
  331. /// more than one symbol at a time. If \p symbols contains a list of
  332. /// undefined symbols in some module, then calling this method is like
  333. /// making one complete pass through the archive to resolve symbols but is
  334. /// more efficient than looking at the individual members. Note that on
  335. /// exit, the symbols resolved by this method will be removed from \p
  336. /// symbols to ensure they are not re-searched on a subsequent call. If
  337. /// you need to retain the list of symbols, make a copy.
  338. /// @brief Look up multiple symbols in the archive.
  339. bool findModulesDefiningSymbols(
  340. std::set<std::string>& symbols, ///< Symbols to be sought
  341. SmallVectorImpl<Module*>& modules, ///< The modules matching \p symbols
  342. std::string* ErrMessage ///< Error msg storage, if non-zero
  343. );
  344. /// This method determines whether the archive is a properly formed llvm
  345. /// bitcode archive. It first makes sure the symbol table has been loaded
  346. /// and has a non-zero size. If it does, then it is an archive. If not,
  347. /// then it tries to load all the bitcode modules of the archive. Finally,
  348. /// it returns whether it was successful.
  349. /// @returns true if the archive is a proper llvm bitcode archive
  350. /// @brief Determine whether the archive is a proper llvm bitcode archive.
  351. bool isBitcodeArchive();
  352. /// @}
  353. /// @name Mutators
  354. /// @{
  355. public:
  356. /// This method is the only way to get the archive written to disk. It
  357. /// creates or overwrites the file specified when \p this was created
  358. /// or opened. The arguments provide options for writing the archive. If
  359. /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
  360. /// and a symbol table of the externally visible function and global
  361. /// variable names is created. If \p TruncateNames is true, the names of the
  362. /// archive members will have their path component stripped and the file
  363. /// name will be truncated at 15 characters. If \p Compress is specified,
  364. /// all archive members will be compressed before being written. If
  365. /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
  366. /// @returns true if an error occurred, \p error set to error message;
  367. /// returns false if the writing succeeded.
  368. /// @brief Write (possibly modified) archive contents to disk
  369. bool writeToDisk(
  370. bool CreateSymbolTable=false, ///< Create Symbol table
  371. bool TruncateNames=false, ///< Truncate the filename to 15 chars
  372. std::string* ErrMessage=0 ///< If non-null, where error msg is set
  373. );
  374. /// This method adds a new file to the archive. The \p filename is examined
  375. /// to determine just enough information to create an ArchiveMember object
  376. /// which is then inserted into the Archive object's ilist at the location
  377. /// given by \p where.
  378. /// @returns true if an error occurred, false otherwise
  379. /// @brief Add a file to the archive.
  380. bool addFileBefore(
  381. const sys::Path& filename, ///< The file to be added
  382. iterator where, ///< Insertion point
  383. std::string* ErrMsg ///< Optional error message location
  384. );
  385. /// @}
  386. /// @name Implementation
  387. /// @{
  388. protected:
  389. /// @brief Construct an Archive for \p filename and optionally map it
  390. /// into memory.
  391. explicit Archive(const sys::Path& filename, LLVMContext& C);
  392. /// @param data The symbol table data to be parsed
  393. /// @param len The length of the symbol table data
  394. /// @param error Set to address of a std::string to get error messages
  395. /// @returns false on error
  396. /// @brief Parse the symbol table at \p data.
  397. bool parseSymbolTable(const void* data,unsigned len,std::string* error);
  398. /// @returns A fully populated ArchiveMember or 0 if an error occurred.
  399. /// @brief Parse the header of a member starting at \p At
  400. ArchiveMember* parseMemberHeader(
  401. const char*&At, ///< The pointer to the location we're parsing
  402. const char*End, ///< The pointer to the end of the archive
  403. std::string* error ///< Optional error message catcher
  404. );
  405. /// @param ErrMessage Set to address of a std::string to get error messages
  406. /// @returns false on error
  407. /// @brief Check that the archive signature is correct
  408. bool checkSignature(std::string* ErrMessage);
  409. /// @param ErrMessage Set to address of a std::string to get error messages
  410. /// @returns false on error
  411. /// @brief Load the entire archive.
  412. bool loadArchive(std::string* ErrMessage);
  413. /// @param ErrMessage Set to address of a std::string to get error messages
  414. /// @returns false on error
  415. /// @brief Load just the symbol table.
  416. bool loadSymbolTable(std::string* ErrMessage);
  417. /// @brief Write the symbol table to an ofstream.
  418. void writeSymbolTable(std::ofstream& ARFile);
  419. /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
  420. /// false, otherwise true. If an error occurs and error is non-null then
  421. /// it will be set to an error message.
  422. /// @returns false if writing member succeeded,
  423. /// returns true if writing member failed, \p error set to error message.
  424. bool writeMember(
  425. const ArchiveMember& member, ///< The member to be written
  426. std::ofstream& ARFile, ///< The file to write member onto
  427. bool CreateSymbolTable, ///< Should symbol table be created?
  428. bool TruncateNames, ///< Should names be truncated to 11 chars?
  429. std::string* ErrMessage ///< If non-null, place were error msg is set
  430. );
  431. /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
  432. bool fillHeader(const ArchiveMember&mbr,
  433. ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
  434. /// @brief Maps archive into memory
  435. bool mapToMemory(std::string* ErrMsg);
  436. /// @brief Frees all the members and unmaps the archive file.
  437. void cleanUpMemory();
  438. /// This type is used to keep track of bitcode modules loaded from the
  439. /// symbol table. It maps the file offset to a pair that consists of the
  440. /// associated ArchiveMember and the Module.
  441. /// @brief Module mapping type
  442. typedef std::map<unsigned,std::pair<Module*,ArchiveMember*> >
  443. ModuleMap;
  444. /// @}
  445. /// @name Data
  446. /// @{
  447. protected:
  448. sys::Path archPath; ///< Path to the archive file we read/write
  449. MembersList members; ///< The ilist of ArchiveMember
  450. MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory
  451. const char* base; ///< Base of the memory mapped file data
  452. SymTabType symTab; ///< The symbol table
  453. std::string strtab; ///< The string table for long file names
  454. unsigned symTabSize; ///< Size in bytes of symbol table
  455. unsigned firstFileOffset; ///< Offset to first normal file.
  456. ModuleMap modules; ///< The modules loaded via symbol lookup.
  457. ArchiveMember* foreignST; ///< This holds the foreign symbol table.
  458. LLVMContext& Context; ///< This holds global data.
  459. /// @}
  460. /// @name Hidden
  461. /// @{
  462. private:
  463. Archive() LLVM_DELETED_FUNCTION;
  464. Archive(const Archive&) LLVM_DELETED_FUNCTION;
  465. Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
  466. /// @}
  467. };
  468. } // End llvm namespace
  469. #endif