llvm.org GIT mirror llvm / 8496fae
Move lib/Archive to tools/llvm-ar. llvm-ar is the only tool that needs to write archive files. Every other tool should be able to use the lib/Object interface. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184083 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
20 changed file(s) with 1859 addition(s) and 1902 deletion(s). Raw diff Collapse all Expand all
+0
-524
include/llvm/Bitcode/Archive.h less more
None //===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This header file declares the Archive and ArchiveMember classes that provide
10 // manipulation of LLVM Archive files. The implementation is provided by the
11 // lib/Bitcode/Archive library. This library is used to read and write
12 // archive (*.a) files that contain LLVM bitcode files (or others).
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_BITCODE_ARCHIVE_H
17 #define LLVM_BITCODE_ARCHIVE_H
18
19 #include "llvm/ADT/ilist.h"
20 #include "llvm/ADT/ilist_node.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/PathV1.h"
23 #include
24 #include
25
26 namespace llvm {
27 class MemoryBuffer;
28
29 // Forward declare classes
30 class Module; // From VMCore
31 class Archive; // Declared below
32 class ArchiveMemberHeader; // Internal implementation class
33 class LLVMContext; // Global data
34
35 /// This class is the main class manipulated by users of the Archive class. It
36 /// holds information about one member of the Archive. It is also the element
37 /// stored by the Archive's ilist, the Archive's main abstraction. Because of
38 /// the special requirements of archive files, users are not permitted to
39 /// construct ArchiveMember instances. You should obtain them from the methods
40 /// of the Archive class instead.
41 /// @brief This class represents a single archive member.
42 class ArchiveMember : public ilist_node {
43 /// @name Types
44 /// @{
45 public:
46 /// These flags are used internally by the archive member to specify various
47 /// characteristics of the member. The various "is" methods below provide
48 /// access to the flags. The flags are not user settable.
49 enum Flags {
50 SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
51 BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
52 BitcodeFlag = 4, ///< Member is bitcode
53 HasPathFlag = 8, ///< Member has a full or partial path
54 HasLongFilenameFlag = 16, ///< Member uses the long filename syntax
55 StringTableFlag = 32 ///< Member is an ar(1) format string table
56 };
57
58 /// @}
59 /// @name Accessors
60 /// @{
61 public:
62 /// @returns the parent Archive instance
63 /// @brief Get the archive associated with this member
64 Archive* getArchive() const { return parent; }
65
66 /// @returns the path to the Archive's file
67 /// @brief Get the path to the archive member
68 const sys::Path& getPath() const { return path; }
69
70 /// The "user" is the owner of the file per Unix security. This may not
71 /// have any applicability on non-Unix systems but is a required component
72 /// of the "ar" file format.
73 /// @brief Get the user associated with this archive member.
74 unsigned getUser() const { return info.getUser(); }
75
76 /// The "group" is the owning group of the file per Unix security. This
77 /// may not have any applicability on non-Unix systems but is a required
78 /// component of the "ar" file format.
79 /// @brief Get the group associated with this archive member.
80 unsigned getGroup() const { return info.getGroup(); }
81
82 /// The "mode" specifies the access permissions for the file per Unix
83 /// security. This may not have any applicability on non-Unix systems but is
84 /// a required component of the "ar" file format.
85 /// @brief Get the permission mode associated with this archive member.
86 unsigned getMode() const { return info.getMode(); }
87
88 /// This method returns the time at which the archive member was last
89 /// modified when it was not in the archive.
90 /// @brief Get the time of last modification of the archive member.
91 sys::TimeValue getModTime() const { return info.getTimestamp(); }
92
93 /// @returns the size of the archive member in bytes.
94 /// @brief Get the size of the archive member.
95 uint64_t getSize() const { return info.getSize(); }
96
97 /// This method returns the total size of the archive member as it
98 /// appears on disk. This includes the file content, the header, the
99 /// long file name if any, and the padding.
100 /// @brief Get total on-disk member size.
101 unsigned getMemberSize() const;
102
103 /// This method will return a pointer to the in-memory content of the
104 /// archive member, if it is available. If the data has not been loaded
105 /// into memory, the return value will be null.
106 /// @returns a pointer to the member's data.
107 /// @brief Get the data content of the archive member
108 const char* getData() const { return data; }
109
110 /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
111 /// @brief Determine if this member is a SVR4 symbol table.
112 bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
113
114 /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
115 /// @brief Determine if this member is a BSD4.4 symbol table.
116 bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
117
118 /// @returns true iff the archive member is the ar(1) string table
119 /// @brief Determine if this member is the ar(1) string table.
120 bool isStringTable() const { return flags&StringTableFlag; }
121
122 /// @returns true iff the archive member is a bitcode file.
123 /// @brief Determine if this member is a bitcode file.
124 bool isBitcode() const { return flags&BitcodeFlag; }
125
126 /// @returns true iff the file name contains a path (directory) component.
127 /// @brief Determine if the member has a path
128 bool hasPath() const { return flags&HasPathFlag; }
129
130 /// Long filenames are an artifact of the ar(1) file format which allows
131 /// up to sixteen characters in its header and doesn't allow a path
132 /// separator character (/). To avoid this, a "long format" member name is
133 /// allowed that doesn't have this restriction. This method determines if
134 /// that "long format" is used for this member.
135 /// @returns true iff the file name uses the long form
136 /// @brief Determine if the member has a long file name
137 bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
138
139 /// This method returns the status info (like Unix stat(2)) for the archive
140 /// member. The status info provides the file's size, permissions, and
141 /// modification time. The contents of the Path::StatusInfo structure, other
142 /// than the size and modification time, may not have utility on non-Unix
143 /// systems.
144 /// @returns the status info for the archive member
145 /// @brief Obtain the status info for the archive member
146 const sys::FileStatus &getFileStatus() const { return info; }
147
148 /// This method causes the archive member to be replaced with the contents
149 /// of the file specified by \p File. The contents of \p this will be
150 /// updated to reflect the new data from \p File. The \p File must exist and
151 /// be readable on entry to this method.
152 /// @returns true if an error occurred, false otherwise
153 /// @brief Replace contents of archive member with a new file.
154 bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
155
156 /// @}
157 /// @name Data
158 /// @{
159 private:
160 Archive* parent; ///< Pointer to parent archive
161 sys::PathWithStatus path; ///< Path of file containing the member
162 sys::FileStatus info; ///< Status info (size,mode,date)
163 unsigned flags; ///< Flags about the archive member
164 const char* data; ///< Data for the member
165
166 /// @}
167 /// @name Constructors
168 /// @{
169 public:
170 /// The default constructor is only used by the Archive's iplist when it
171 /// constructs the list's sentry node.
172 ArchiveMember();
173
174 private:
175 /// Used internally by the Archive class to construct an ArchiveMember.
176 /// The contents of the ArchiveMember are filled out by the Archive class.
177 explicit ArchiveMember(Archive *PAR);
178
179 // So Archive can construct an ArchiveMember
180 friend class llvm::Archive;
181 /// @}
182 };
183
184 /// This class defines the interface to LLVM Archive files. The Archive class
185 /// presents the archive file as an ilist of ArchiveMember objects. The members
186 /// can be rearranged in any fashion either by directly editing the ilist or by
187 /// using editing methods on the Archive class (recommended). The Archive
188 /// class also provides several ways of accessing the archive file for various
189 /// purposes such as editing and linking. Full symbol table support is provided
190 /// for loading only those files that resolve symbols. Note that read
191 /// performance of this library is _crucial_ for performance of JIT type
192 /// applications and the linkers. Consequently, the implementation of the class
193 /// is optimized for reading.
194 class Archive {
195
196 /// @name Types
197 /// @{
198 public:
199 /// This is the ilist type over which users may iterate to examine
200 /// the contents of the archive
201 /// @brief The ilist type of ArchiveMembers that Archive contains.
202 typedef iplist MembersList;
203
204 /// @brief Forward mutable iterator over ArchiveMember
205 typedef MembersList::iterator iterator;
206
207 /// @brief Forward immutable iterator over ArchiveMember
208 typedef MembersList::const_iterator const_iterator;
209
210 /// @brief Reverse mutable iterator over ArchiveMember
211 typedef std::reverse_iterator reverse_iterator;
212
213 /// @brief Reverse immutable iterator over ArchiveMember
214 typedef std::reverse_iterator const_reverse_iterator;
215
216 /// @brief The in-memory version of the symbol table
217 typedef std::map SymTabType;
218
219 /// @}
220 /// @name ilist accessor methods
221 /// @{
222 public:
223 inline iterator begin() { return members.begin(); }
224 inline const_iterator begin() const { return members.begin(); }
225 inline iterator end () { return members.end(); }
226 inline const_iterator end () const { return members.end(); }
227
228 inline reverse_iterator rbegin() { return members.rbegin(); }
229 inline const_reverse_iterator rbegin() const { return members.rbegin(); }
230 inline reverse_iterator rend () { return members.rend(); }
231 inline const_reverse_iterator rend () const { return members.rend(); }
232
233 inline size_t size() const { return members.size(); }
234 inline bool empty() const { return members.empty(); }
235 inline const ArchiveMember& front() const { return members.front(); }
236 inline ArchiveMember& front() { return members.front(); }
237 inline const ArchiveMember& back() const { return members.back(); }
238 inline ArchiveMember& back() { return members.back(); }
239
240 /// @}
241 /// @name ilist mutator methods
242 /// @{
243 public:
244 /// This method splices a \p src member from an archive (possibly \p this),
245 /// to a position just before the member given by \p dest in \p this. When
246 /// the archive is written, \p src will be written in its new location.
247 /// @brief Move a member to a new location
248 inline void splice(iterator dest, Archive& arch, iterator src)
249 { return members.splice(dest,arch.members,src); }
250
251 /// This method erases a \p target member from the archive. When the
252 /// archive is written, it will no longer contain \p target. The associated
253 /// ArchiveMember is deleted.
254 /// @brief Erase a member.
255 inline iterator erase(iterator target) { return members.erase(target); }
256
257 /// @}
258 /// @name Constructors
259 /// @{
260 public:
261 /// Create an empty archive file and associate it with the \p Filename. This
262 /// method does not actually create the archive disk file. It creates an
263 /// empty Archive object. If the writeToDisk method is called, the archive
264 /// file \p Filename will be created at that point, with whatever content
265 /// the returned Archive object has at that time.
266 /// @returns An Archive* that represents the new archive file.
267 /// @brief Create an empty Archive.
268 static Archive* CreateEmpty(
269 const sys::Path& Filename,///< Name of the archive to (eventually) create.
270 LLVMContext& C ///< Context to use for global information
271 );
272
273 /// Open an existing archive and load its contents in preparation for
274 /// editing. After this call, the member ilist is completely populated based
275 /// on the contents of the archive file. You should use this form of open if
276 /// you intend to modify the archive or traverse its contents (e.g. for
277 /// printing).
278 /// @brief Open and load an archive file
279 static Archive* OpenAndLoad(
280 const sys::Path& filePath, ///< The file path to open and load
281 LLVMContext& C, ///< The context to use for global information
282 std::string* ErrorMessage ///< An optional error string
283 );
284
285 /// This method opens an existing archive file from \p Filename and reads in
286 /// its symbol table without reading in any of the archive's members. This
287 /// reduces both I/O and cpu time in opening the archive if it is to be used
288 /// solely for symbol lookup (e.g. during linking). The \p Filename must
289 /// exist and be an archive file or an error will be returned. This form
290 /// of opening the archive is intended for read-only operations that need to
291 /// locate members via the symbol table for link editing. Since the archve
292 /// members are not read by this method, the archive will appear empty upon
293 /// return. If editing operations are performed on the archive, they will
294 /// completely replace the contents of the archive! It is recommended that
295 /// if this form of opening the archive is used that only the symbol table
296 /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
297 /// findModulesDefiningSymbols) be used.
298 /// @returns an Archive* that represents the archive file, or null on error.
299 /// @brief Open an existing archive and load its symbols.
300 static Archive* OpenAndLoadSymbols(
301 const sys::Path& Filename, ///< Name of the archive file to open
302 LLVMContext& C, ///< The context to use for global info
303 std::string* ErrorMessage=0 ///< An optional error string
304 );
305
306 /// This destructor cleans up the Archive object, releases all memory, and
307 /// closes files. It does nothing with the archive file on disk. If you
308 /// haven't used the writeToDisk method by the time the destructor is
309 /// called, all changes to the archive will be lost.
310 /// @brief Destruct in-memory archive
311 ~Archive();
312
313 /// @}
314 /// @name Accessors
315 /// @{
316 public:
317 /// @returns the path to the archive file.
318 /// @brief Get the archive path.
319 const sys::Path& getPath() { return archPath; }
320
321 /// This method is provided so that editing methods can be invoked directly
322 /// on the Archive's iplist of ArchiveMember. However, it is recommended
323 /// that the usual STL style iterator interface be used instead.
324 /// @returns the iplist of ArchiveMember
325 /// @brief Get the iplist of the members
326 MembersList& getMembers() { return members; }
327
328 /// This method allows direct query of the Archive's symbol table. The
329 /// symbol table is a std::map of std::string (the symbol) to unsigned (the
330 /// file offset). Note that for efficiency reasons, the offset stored in
331 /// the symbol table is not the actual offset. It is the offset from the
332 /// beginning of the first "real" file member (after the symbol table). Use
333 /// the getFirstFileOffset() to obtain that offset and add this value to the
334 /// offset in the symbol table to obtain the real file offset. Note that
335 /// there is purposefully no interface provided by Archive to look up
336 /// members by their offset. Use the findModulesDefiningSymbols and
337 /// findModuleDefiningSymbol methods instead.
338 /// @returns the Archive's symbol table.
339 /// @brief Get the archive's symbol table
340 const SymTabType& getSymbolTable() { return symTab; }
341
342 /// This method returns the offset in the archive file to the first "real"
343 /// file member. Archive files, on disk, have a signature and might have a
344 /// symbol table that precedes the first actual file member. This method
345 /// allows you to determine what the size of those fields are.
346 /// @returns the offset to the first "real" file member in the archive.
347 /// @brief Get the offset to the first "real" file member in the archive.
348 unsigned getFirstFileOffset() { return firstFileOffset; }
349
350 /// This method will scan the archive for bitcode modules, interpret them
351 /// and return a vector of the instantiated modules in \p Modules. If an
352 /// error occurs, this method will return true. If \p ErrMessage is not null
353 /// and an error occurs, \p *ErrMessage will be set to a string explaining
354 /// the error that occurred.
355 /// @returns true if an error occurred
356 /// @brief Instantiate all the bitcode modules located in the archive
357 bool getAllModules(std::vector& Modules, std::string* ErrMessage);
358
359 /// This accessor looks up the \p symbol in the archive's symbol table and
360 /// returns the associated module that defines that symbol. This method can
361 /// be called as many times as necessary. This is handy for linking the
362 /// archive into another module based on unresolved symbols. Note that the
363 /// Module returned by this accessor should not be deleted by the caller. It
364 /// is managed internally by the Archive class. It is possible that multiple
365 /// calls to this accessor will return the same Module instance because the
366 /// associated module defines multiple symbols.
367 /// @returns The Module* found or null if the archive does not contain a
368 /// module that defines the \p symbol.
369 /// @brief Look up a module by symbol name.
370 Module* findModuleDefiningSymbol(
371 const std::string& symbol, ///< Symbol to be sought
372 std::string* ErrMessage ///< Error message storage, if non-zero
373 );
374
375 /// This method is similar to findModuleDefiningSymbol but allows lookup of
376 /// more than one symbol at a time. If \p symbols contains a list of
377 /// undefined symbols in some module, then calling this method is like
378 /// making one complete pass through the archive to resolve symbols but is
379 /// more efficient than looking at the individual members. Note that on
380 /// exit, the symbols resolved by this method will be removed from \p
381 /// symbols to ensure they are not re-searched on a subsequent call. If
382 /// you need to retain the list of symbols, make a copy.
383 /// @brief Look up multiple symbols in the archive.
384 bool findModulesDefiningSymbols(
385 std::set& symbols, ///< Symbols to be sought
386 SmallVectorImpl& modules, ///< The modules matching \p symbols
387 std::string* ErrMessage ///< Error msg storage, if non-zero
388 );
389
390 /// This method determines whether the archive is a properly formed llvm
391 /// bitcode archive. It first makes sure the symbol table has been loaded
392 /// and has a non-zero size. If it does, then it is an archive. If not,
393 /// then it tries to load all the bitcode modules of the archive. Finally,
394 /// it returns whether it was successful.
395 /// @returns true if the archive is a proper llvm bitcode archive
396 /// @brief Determine whether the archive is a proper llvm bitcode archive.
397 bool isBitcodeArchive();
398
399 /// @}
400 /// @name Mutators
401 /// @{
402 public:
403 /// This method is the only way to get the archive written to disk. It
404 /// creates or overwrites the file specified when \p this was created
405 /// or opened. The arguments provide options for writing the archive. If
406 /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
407 /// and a symbol table of the externally visible function and global
408 /// variable names is created. If \p TruncateNames is true, the names of the
409 /// archive members will have their path component stripped and the file
410 /// name will be truncated at 15 characters. If \p Compress is specified,
411 /// all archive members will be compressed before being written. If
412 /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
413 /// @returns true if an error occurred, \p error set to error message;
414 /// returns false if the writing succeeded.
415 /// @brief Write (possibly modified) archive contents to disk
416 bool writeToDisk(
417 bool CreateSymbolTable=false, ///< Create Symbol table
418 bool TruncateNames=false, ///< Truncate the filename to 15 chars
419 std::string* ErrMessage=0 ///< If non-null, where error msg is set
420 );
421
422 /// This method adds a new file to the archive. The \p filename is examined
423 /// to determine just enough information to create an ArchiveMember object
424 /// which is then inserted into the Archive object's ilist at the location
425 /// given by \p where.
426 /// @returns true if an error occurred, false otherwise
427 /// @brief Add a file to the archive.
428 bool addFileBefore(
429 const sys::Path& filename, ///< The file to be added
430 iterator where, ///< Insertion point
431 std::string* ErrMsg ///< Optional error message location
432 );
433
434 /// @}
435 /// @name Implementation
436 /// @{
437 protected:
438 /// @brief Construct an Archive for \p filename and optionally map it
439 /// into memory.
440 explicit Archive(const sys::Path& filename, LLVMContext& C);
441
442 /// @returns A fully populated ArchiveMember or 0 if an error occurred.
443 /// @brief Parse the header of a member starting at \p At
444 ArchiveMember* parseMemberHeader(
445 const char*&At, ///< The pointer to the location we're parsing
446 const char*End, ///< The pointer to the end of the archive
447 std::string* error ///< Optional error message catcher
448 );
449
450 /// @param ErrMessage Set to address of a std::string to get error messages
451 /// @returns false on error
452 /// @brief Check that the archive signature is correct
453 bool checkSignature(std::string* ErrMessage);
454
455 /// @param ErrMessage Set to address of a std::string to get error messages
456 /// @returns false on error
457 /// @brief Load the entire archive.
458 bool loadArchive(std::string* ErrMessage);
459
460 /// @param ErrMessage Set to address of a std::string to get error messages
461 /// @returns false on error
462 /// @brief Load just the symbol table.
463 bool loadSymbolTable(std::string* ErrMessage);
464
465 /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
466 /// false, otherwise true. If an error occurs and error is non-null then
467 /// it will be set to an error message.
468 /// @returns false if writing member succeeded,
469 /// returns true if writing member failed, \p error set to error message.
470 bool writeMember(
471 const ArchiveMember& member, ///< The member to be written
472 std::ofstream& ARFile, ///< The file to write member onto
473 bool CreateSymbolTable, ///< Should symbol table be created?
474 bool TruncateNames, ///< Should names be truncated to 11 chars?
475 std::string* ErrMessage ///< If non-null, place were error msg is set
476 );
477
478 /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
479 bool fillHeader(const ArchiveMember&mbr,
480 ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
481
482 /// @brief Maps archive into memory
483 bool mapToMemory(std::string* ErrMsg);
484
485 /// @brief Frees all the members and unmaps the archive file.
486 void cleanUpMemory();
487
488 /// This type is used to keep track of bitcode modules loaded from the
489 /// symbol table. It maps the file offset to a pair that consists of the
490 /// associated ArchiveMember and the Module.
491 /// @brief Module mapping type
492 typedef std::map >
493 ModuleMap;
494
495
496 /// @}
497 /// @name Data
498 /// @{
499 protected:
500 sys::Path archPath; ///< Path to the archive file we read/write
501 MembersList members; ///< The ilist of ArchiveMember
502 MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory
503 const char* base; ///< Base of the memory mapped file data
504 SymTabType symTab; ///< The symbol table
505 std::string strtab; ///< The string table for long file names
506 unsigned symTabSize; ///< Size in bytes of symbol table
507 unsigned firstFileOffset; ///< Offset to first normal file.
508 ModuleMap modules; ///< The modules loaded via symbol lookup.
509 ArchiveMember* foreignST; ///< This holds the foreign symbol table.
510 LLVMContext& Context; ///< This holds global data.
511 /// @}
512 /// @name Hidden
513 /// @{
514 private:
515 Archive() LLVM_DELETED_FUNCTION;
516 Archive(const Archive&) LLVM_DELETED_FUNCTION;
517 Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
518 /// @}
519 };
520
521 } // End llvm namespace
522
523 #endif
+0
-254
lib/Archive/Archive.cpp less more
None //===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the implementation of the Archive and ArchiveMember
10 // classes that is common to both reading and writing archives..
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Bitcode/Archive.h"
15 #include "ArchiveInternals.h"
16 #include "llvm/Bitcode/ReaderWriter.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Process.h"
21 #include "llvm/Support/system_error.h"
22 #include
23 #include
24 using namespace llvm;
25
26 // getMemberSize - compute the actual physical size of the file member as seen
27 // on disk. This isn't the size of member's payload. Use getSize() for that.
28 unsigned
29 ArchiveMember::getMemberSize() const {
30 // Basically its the file size plus the header size
31 unsigned result = info.fileSize + sizeof(ArchiveMemberHeader);
32
33 // If it has a long filename, include the name length
34 if (hasLongFilename())
35 result += path.str().length() + 1;
36
37 // If its now odd lengthed, include the padding byte
38 if (result % 2 != 0 )
39 result++;
40
41 return result;
42 }
43
44 // This default constructor is only use by the ilist when it creates its
45 // sentry node. We give it specific static values to make it stand out a bit.
46 ArchiveMember::ArchiveMember()
47 : parent(0), path("--invalid--"), flags(0), data(0)
48 {
49 info.user = sys::Process::GetCurrentUserId();
50 info.group = sys::Process::GetCurrentGroupId();
51 info.mode = 0777;
52 info.fileSize = 0;
53 info.modTime = sys::TimeValue::now();
54 }
55
56 // This is the constructor that the Archive class uses when it is building or
57 // reading an archive. It just defaults a few things and ensures the parent is
58 // set for the iplist. The Archive class fills in the ArchiveMember's data.
59 // This is required because correctly setting the data may depend on other
60 // things in the Archive.
61 ArchiveMember::ArchiveMember(Archive* PAR)
62 : parent(PAR), path(), flags(0), data(0)
63 {
64 }
65
66 // This method allows an ArchiveMember to be replaced with the data for a
67 // different file, presumably as an update to the member. It also makes sure
68 // the flags are reset correctly.
69 bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
70 bool Exists;
71 if (sys::fs::exists(newFile.str(), Exists) || !Exists) {
72 if (ErrMsg)
73 *ErrMsg = "Can not replace an archive member with a non-existent file";
74 return true;
75 }
76
77 data = 0;
78 path = newFile;
79
80 // SVR4 symbol tables have an empty name
81 if (path.str() == ARFILE_SVR4_SYMTAB_NAME)
82 flags |= SVR4SymbolTableFlag;
83 else
84 flags &= ~SVR4SymbolTableFlag;
85
86 // BSD4.4 symbol tables have a special name
87 if (path.str() == ARFILE_BSD4_SYMTAB_NAME)
88 flags |= BSD4SymbolTableFlag;
89 else
90 flags &= ~BSD4SymbolTableFlag;
91
92 // String table name
93 if (path.str() == ARFILE_STRTAB_NAME)
94 flags |= StringTableFlag;
95 else
96 flags &= ~StringTableFlag;
97
98 // If it has a slash then it has a path
99 bool hasSlash = path.str().find('/') != std::string::npos;
100 if (hasSlash)
101 flags |= HasPathFlag;
102 else
103 flags &= ~HasPathFlag;
104
105 // If it has a slash or its over 15 chars then its a long filename format
106 if (hasSlash || path.str().length() > 15)
107 flags |= HasLongFilenameFlag;
108 else
109 flags &= ~HasLongFilenameFlag;
110
111 // Get the signature and status info
112 const char* signature = (const char*) data;
113 SmallString<4> magic;
114 if (!signature) {
115 sys::fs::get_magic(path.str(), magic.capacity(), magic);
116 signature = magic.c_str();
117 const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg);
118 if (FSinfo)
119 info = *FSinfo;
120 else
121 return true;
122 }
123
124 // Determine what kind of file it is.
125 if (sys::fs::identify_magic(StringRef(signature, 4)) ==
126 sys::fs::file_magic::bitcode)
127 flags |= BitcodeFlag;
128 else
129 flags &= ~BitcodeFlag;
130
131 return false;
132 }
133
134 // Archive constructor - this is the only constructor that gets used for the
135 // Archive class. Everything else (default,copy) is deprecated. This just
136 // initializes and maps the file into memory, if requested.
137 Archive::Archive(const sys::Path& filename, LLVMContext& C)
138 : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
139 symTabSize(0), firstFileOffset(0), modules(), foreignST(0), Context(C) {
140 }
141
142 bool
143 Archive::mapToMemory(std::string* ErrMsg) {
144 OwningPtr File;
145 if (error_code ec = MemoryBuffer::getFile(archPath.c_str(), File)) {
146 if (ErrMsg)
147 *ErrMsg = ec.message();
148 return true;
149 }
150 mapfile = File.take();
151 base = mapfile->getBufferStart();
152 return false;
153 }
154
155 void Archive::cleanUpMemory() {
156 // Shutdown the file mapping
157 delete mapfile;
158 mapfile = 0;
159 base = 0;
160
161 // Forget the entire symbol table
162 symTab.clear();
163 symTabSize = 0;
164
165 firstFileOffset = 0;
166
167 // Free the foreign symbol table member
168 if (foreignST) {
169 delete foreignST;
170 foreignST = 0;
171 }
172
173 // Delete any Modules and ArchiveMember's we've allocated as a result of
174 // symbol table searches.
175 for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) {
176 delete I->second.first;
177 delete I->second.second;
178 }
179 }
180
181 // Archive destructor - just clean up memory
182 Archive::~Archive() {
183 cleanUpMemory();
184 }
185
186
187
188 static void getSymbols(Module*M, std::vector& symbols) {
189 // Loop over global variables
190 for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI)
191 if (!GI->isDeclaration() && !GI->hasLocalLinkage())
192 if (!GI->getName().empty())
193 symbols.push_back(GI->getName());
194
195 // Loop over functions
196 for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI)
197 if (!FI->isDeclaration() && !FI->hasLocalLinkage())
198 if (!FI->getName().empty())
199 symbols.push_back(FI->getName());
200
201 // Loop over aliases
202 for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end();
203 AI != AE; ++AI) {
204 if (AI->hasName())
205 symbols.push_back(AI->getName());
206 }
207 }
208
209 // Get just the externally visible defined symbols from the bitcode
210 bool llvm::GetBitcodeSymbols(const sys::Path& fName,
211 LLVMContext& Context,
212 std::vector& symbols,
213 std::string* ErrMsg) {
214 OwningPtr Buffer;
215 if (error_code ec = MemoryBuffer::getFileOrSTDIN(fName.c_str(), Buffer)) {
216 if (ErrMsg) *ErrMsg = "Could not open file '" + fName.str() + "'" + ": "
217 + ec.message();
218 return true;
219 }
220
221 Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
222 if (!M)
223 return true;
224
225 // Get the symbols
226 getSymbols(M, symbols);
227
228 // Done with the module.
229 delete M;
230 return true;
231 }
232
233 Module*
234 llvm::GetBitcodeSymbols(const char *BufPtr, unsigned Length,
235 const std::string& ModuleID,
236 LLVMContext& Context,
237 std::vector& symbols,
238 std::string* ErrMsg) {
239 // Get the module.
240 OwningPtr Buffer(
241 MemoryBuffer::getMemBufferCopy(StringRef(BufPtr, Length),ModuleID.c_str()));
242
243 Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
244 if (!M)
245 return 0;
246
247 // Get the symbols
248 getSymbols(M, symbols);
249
250 // Done with the module. Note that it's the caller's responsibility to delete
251 // the Module.
252 return M;
253 }
+0
-87
lib/Archive/ArchiveInternals.h less more
None //===-- lib/Archive/ArchiveInternals.h -------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Internal implementation header for LLVM Archive files.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LIB_ARCHIVE_ARCHIVEINTERNALS_H
14 #define LIB_ARCHIVE_ARCHIVEINTERNALS_H
15
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/Bitcode/Archive.h"
18 #include "llvm/Support/TimeValue.h"
19 #include
20
21 #define ARFILE_MAGIC "!\n" ///< magic string
22 #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string
23 #define ARFILE_SVR4_SYMTAB_NAME "/ " ///< SVR4 symtab entry name
24 #define ARFILE_BSD4_SYMTAB_NAME "__.SYMDEF SORTED" ///< BSD4 symtab entry name
25 #define ARFILE_STRTAB_NAME "// " ///< Name of string table
26 #define ARFILE_PAD "\n" ///< inter-file align padding
27 #define ARFILE_MEMBER_MAGIC "`\n" ///< fmag field magic #
28
29 namespace llvm {
30
31 class LLVMContext;
32
33 /// The ArchiveMemberHeader structure is used internally for bitcode
34 /// archives.
35 /// The header precedes each file member in the archive. This structure is
36 /// defined using character arrays for direct and correct interpretation
37 /// regardless of the endianess of the machine that produced it.
38 /// @brief Archive File Member Header
39 class ArchiveMemberHeader {
40 /// @name Data
41 /// @{
42 public:
43 char name[16]; ///< Name of the file member.
44 char date[12]; ///< File date, decimal seconds since Epoch
45 char uid[6]; ///< user id in ASCII decimal
46 char gid[6]; ///< group id in ASCII decimal
47 char mode[8]; ///< file mode in ASCII octal
48 char size[10]; ///< file size in ASCII decimal
49 char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR
50
51 /// @}
52 /// @name Methods
53 /// @{
54 public:
55 void init() {
56 memset(name,' ',16);
57 memset(date,' ',12);
58 memset(uid,' ',6);
59 memset(gid,' ',6);
60 memset(mode,' ',8);
61 memset(size,' ',10);
62 fmag[0] = '`';
63 fmag[1] = '\n';
64 }
65
66 bool checkSignature() const {
67 return 0 == memcmp(fmag, ARFILE_MEMBER_MAGIC,2);
68 }
69 };
70
71 // Get just the externally visible defined symbols from the bitcode
72 bool GetBitcodeSymbols(const sys::Path& fName,
73 LLVMContext& Context,
74 std::vector& symbols,
75 std::string* ErrMsg);
76
77 Module* GetBitcodeSymbols(const char *Buffer, unsigned Length,
78 const std::string& ModuleID,
79 LLVMContext& Context,
80 std::vector& symbols,
81 std::string* ErrMsg);
82 }
83
84 #endif
85
86 // vim: sw=2 ai
+0
-557
lib/Archive/ArchiveReader.cpp less more
None //===-- ArchiveReader.cpp - Read LLVM archive files -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Builds up standard unix archive files (.a) containing LLVM bitcode.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Bitcode/Archive.h"
14 #include "ArchiveInternals.h"
15 #include "llvm/ADT/OwningPtr.h"
16 #include "llvm/ADT/SmallPtrSet.h"
17 #include "llvm/Bitcode/ReaderWriter.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include
22 #include
23 using namespace llvm;
24
25 /// Read a variable-bit-rate encoded unsigned integer
26 static inline unsigned readInteger(const char*&At, const char*End) {
27 unsigned Shift = 0;
28 unsigned Result = 0;
29
30 do {
31 if (At == End)
32 return Result;
33 Result |= (unsigned)((*At++) & 0x7F) << Shift;
34 Shift += 7;
35 } while (At[-1] & 0x80);
36 return Result;
37 }
38
39 // This member parses an ArchiveMemberHeader that is presumed to be pointed to
40 // by At. The At pointer is updated to the byte just after the header, which
41 // can be variable in size.
42 ArchiveMember*
43 Archive::parseMemberHeader(const char*& At, const char* End, std::string* error)
44 {
45 if (At + sizeof(ArchiveMemberHeader) >= End) {
46 if (error)
47 *error = "Unexpected end of file";
48 return 0;
49 }
50
51 // Cast archive member header
52 const ArchiveMemberHeader* Hdr = (const ArchiveMemberHeader*)At;
53 At += sizeof(ArchiveMemberHeader);
54
55 int flags = 0;
56 int MemberSize = atoi(Hdr->size);
57 assert(MemberSize >= 0);
58
59 // Check the size of the member for sanity
60 if (At + MemberSize > End) {
61 if (error)
62 *error = "invalid member length in archive file";
63 return 0;
64 }
65
66 // Check the member signature
67 if (!Hdr->checkSignature()) {
68 if (error)
69 *error = "invalid file member signature";
70 return 0;
71 }
72
73 // Convert and check the member name
74 // The empty name ( '/' and 15 blanks) is for a foreign (non-LLVM) symbol
75 // table. The special name "//" and 14 blanks is for a string table, used
76 // for long file names. This library doesn't generate either of those but
77 // it will accept them. If the name starts with #1/ and the remainder is
78 // digits, then those digits specify the length of the name that is
79 // stored immediately following the header. Anything else is a regular, short
80 // filename that is terminated with a '/' and blanks.
81
82 std::string pathname;
83 switch (Hdr->name[0]) {
84 case '#':
85 if (Hdr->name[1] == '1' && Hdr->name[2] == '/') {
86 if (isdigit(Hdr->name[3])) {
87 unsigned len = atoi(&Hdr->name[3]);
88 const char *nulp = (const char *)memchr(At, '\0', len);
89 pathname.assign(At, nulp != 0 ? (uintptr_t)(nulp - At) : len);
90 At += len;
91 MemberSize -= len;
92 flags |= ArchiveMember::HasLongFilenameFlag;
93 } else {
94 if (error)
95 *error = "invalid long filename";
96 return 0;
97 }
98 }
99 break;
100 case '/':
101 if (Hdr->name[1]== '/') {
102 if (0 == memcmp(Hdr->name, ARFILE_STRTAB_NAME, 16)) {
103 pathname.assign(ARFILE_STRTAB_NAME);
104 flags |= ArchiveMember::StringTableFlag;
105 } else {
106 if (error)
107 *error = "invalid string table name";
108 return 0;
109 }
110 } else if (Hdr->name[1] == ' ') {
111 if (0 == memcmp(Hdr->name, ARFILE_SVR4_SYMTAB_NAME, 16)) {
112 pathname.assign(ARFILE_SVR4_SYMTAB_NAME);
113 flags |= ArchiveMember::SVR4SymbolTableFlag;
114 } else {
115 if (error)
116 *error = "invalid SVR4 symbol table name";
117 return 0;
118 }
119 } else if (isdigit(Hdr->name[1])) {
120 unsigned index = atoi(&Hdr->name[1]);
121 if (index < strtab.length()) {
122 const char* namep = strtab.c_str() + index;
123 const char* endp = strtab.c_str() + strtab.length();
124 const char* p = namep;
125 const char* last_p = p;
126 while (p < endp) {
127 if (*p == '\n' && *last_p == '/') {
128 pathname.assign(namep, last_p - namep);
129 flags |= ArchiveMember::HasLongFilenameFlag;
130 break;
131 }
132 last_p = p;
133 p++;
134 }
135 if (p >= endp) {
136 if (error)
137 *error = "missing name terminator in string table";
138 return 0;
139 }
140 } else {
141 if (error)
142 *error = "name index beyond string table";
143 return 0;
144 }
145 }
146 break;
147 case '_':
148 if (Hdr->name[1] == '_' &&
149 (0 == memcmp(Hdr->name, ARFILE_BSD4_SYMTAB_NAME, 16))) {
150 pathname.assign(ARFILE_BSD4_SYMTAB_NAME);
151 flags |= ArchiveMember::BSD4SymbolTableFlag;
152 break;
153 }
154 /* FALL THROUGH */
155
156 default:
157 const char* slash = (const char*) memchr(Hdr->name, '/', 16);
158 if (slash == 0)
159 slash = Hdr->name + 16;
160 pathname.assign(Hdr->name, slash - Hdr->name);
161 break;
162 }
163
164 // Determine if this is a bitcode file
165 if (sys::fs::identify_magic(StringRef(At, 4)) ==
166 sys::fs::file_magic::bitcode)
167 flags |= ArchiveMember::BitcodeFlag;
168 else
169 flags &= ~ArchiveMember::BitcodeFlag;
170
171 // Instantiate the ArchiveMember to be filled
172 ArchiveMember* member = new ArchiveMember(this);
173
174 // Fill in fields of the ArchiveMember
175 member->parent = this;
176 member->path.set(pathname);
177 member->info.fileSize = MemberSize;
178 member->info.modTime.fromEpochTime(atoi(Hdr->date));
179 unsigned int mode;
180 sscanf(Hdr->mode, "%o", &mode);
181 member->info.mode = mode;
182 member->info.user = atoi(Hdr->uid);
183 member->info.group = atoi(Hdr->gid);
184 member->flags = flags;
185 member->data = At;
186
187 return member;
188 }
189
190 bool
191 Archive::checkSignature(std::string* error) {
192 // Check the magic string at file's header
193 if (mapfile->getBufferSize() < 8 || memcmp(base, ARFILE_MAGIC, 8)) {
194 if (error)
195 *error = "invalid signature for an archive file";
196 return false;
197 }
198 return true;
199 }
200
201 // This function loads the entire archive and fully populates its ilist with
202 // the members of the archive file. This is typically used in preparation for
203 // editing the contents of the archive.
204 bool
205 Archive::loadArchive(std::string* error) {
206
207 // Set up parsing
208 members.clear();
209 symTab.clear();
210 const char *At = base;
211 const char *End = mapfile->getBufferEnd();
212
213 if (!checkSignature(error))
214 return false;
215
216 At += 8; // Skip the magic string.
217
218 bool foundFirstFile = false;
219 while (At < End) {
220 // parse the member header
221 const char* Save = At;
222 ArchiveMember* mbr = parseMemberHeader(At, End, error);
223 if (!mbr)
224 return false;
225
226 // check if this is the foreign symbol table
227 if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
228 // We just save this but don't do anything special
229 // with it. It doesn't count as the "first file".
230 if (foreignST) {
231 // What? Multiple foreign symbol tables? Just chuck it
232 // and retain the last one found.
233 delete foreignST;
234 }
235 foreignST = mbr;
236 At += mbr->getSize();
237 if ((intptr_t(At) & 1) == 1)
238 At++;
239 } else if (mbr->isStringTable()) {
240 // Simply suck the entire string table into a string
241 // variable. This will be used to get the names of the
242 // members that use the "/ddd" format for their names
243 // (SVR4 style long names).
244 strtab.assign(At, mbr->getSize());
245 At += mbr->getSize();
246 if ((intptr_t(At) & 1) == 1)
247 At++;
248 delete mbr;
249 } else {
250 // This is just a regular file. If its the first one, save its offset.
251 // Otherwise just push it on the list and move on to the next file.
252 if (!foundFirstFile) {
253 firstFileOffset = Save - base;
254 foundFirstFile = true;
255 }
256 members.push_back(mbr);
257 At += mbr->getSize();
258 if ((intptr_t(At) & 1) == 1)
259 At++;
260 }
261 }
262 return true;
263 }
264
265 // Open and completely load the archive file.
266 Archive*
267 Archive::OpenAndLoad(const sys::Path& File, LLVMContext& C,
268 std::string* ErrorMessage) {
269 OwningPtr result ( new Archive(File, C));
270 if (result->mapToMemory(ErrorMessage))
271 return NULL;
272 if (!result->loadArchive(ErrorMessage))
273 return NULL;
274 return result.take();
275 }
276
277 // Get all the bitcode modules from the archive
278 bool
279 Archive::getAllModules(std::vector& Modules,
280 std::string* ErrMessage) {
281
282 for (iterator I=begin(), E=end(); I != E; ++I) {
283 if (I->isBitcode()) {
284 std::string FullMemberName = archPath.str() +
285 "(" + I->getPath().str() + ")";
286 MemoryBuffer *Buffer =
287 MemoryBuffer::getMemBufferCopy(StringRef(I->getData(), I->getSize()),
288 FullMemberName.c_str());
289
290 Module *M = ParseBitcodeFile(Buffer, Context, ErrMessage);
291 delete Buffer;
292 if (!M)
293 return true;
294
295 Modules.push_back(M);
296 }
297 }
298 return false;
299 }
300
301 // Load just the symbol table from the archive file
302 bool
303 Archive::loadSymbolTable(std::string* ErrorMsg) {
304
305 // Set up parsing
306 members.clear();
307 symTab.clear();
308 const char *At = base;
309 const char *End = mapfile->getBufferEnd();
310
311 // Make sure we're dealing with an archive
312 if (!checkSignature(ErrorMsg))
313 return false;
314
315 At += 8; // Skip signature
316
317 // Parse the first file member header
318 const char* FirstFile = At;
319 ArchiveMember* mbr = parseMemberHeader(At, End, ErrorMsg);
320 if (!mbr)
321 return false;
322
323 if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
324 // Skip the foreign symbol table, we don't do anything with it
325 At += mbr->getSize();
326 if ((intptr_t(At) & 1) == 1)
327 At++;
328 delete mbr;
329
330 // Read the next one
331 FirstFile = At;
332 mbr = parseMemberHeader(At, End, ErrorMsg);
333 if (!mbr) {
334 delete mbr;
335 return false;
336 }
337 }
338
339 if (mbr->isStringTable()) {
340 // Process the string table entry
341 strtab.assign((const char*)mbr->getData(), mbr->getSize());
342 At += mbr->getSize();
343 if ((intptr_t(At) & 1) == 1)
344 At++;
345 delete mbr;
346 // Get the next one
347 FirstFile = At;
348 mbr = parseMemberHeader(At, End, ErrorMsg);
349 if (!mbr) {
350 delete mbr;
351 return false;
352 }
353 }
354
355 // There's no symbol table in the file. We have to rebuild it from scratch
356 // because the intent of this method is to get the symbol table loaded so
357 // it can be searched efficiently.
358 // Add the member to the members list
359 members.push_back(mbr);
360
361 firstFileOffset = FirstFile - base;
362 return true;
363 }
364
365 // Open the archive and load just the symbol tables
366 Archive* Archive::OpenAndLoadSymbols(const sys::Path& File,
367 LLVMContext& C,
368 std::string* ErrorMessage) {
369 OwningPtr result ( new Archive(File, C) );
370 if (result->mapToMemory(ErrorMessage))
371 return NULL;
372 if (!result->loadSymbolTable(ErrorMessage))
373 return NULL;
374 return result.take();
375 }
376
377 // Look up one symbol in the symbol table and return the module that defines
378 // that symbol.
379 Module*
380 Archive::findModuleDefiningSymbol(const std::string& symbol,
381 std::string* ErrMsg) {
382 SymTabType::iterator SI = symTab.find(symbol);
383 if (SI == symTab.end())
384 return 0;
385
386 // The symbol table was previously constructed assuming that the members were
387 // written without the symbol table header. Because VBR encoding is used, the
388 // values could not be adjusted to account for the offset of the symbol table
389 // because that could affect the size of the symbol table due to VBR encoding.
390 // We now have to account for this by adjusting the offset by the size of the
391 // symbol table and its header.
392 unsigned fileOffset =
393 SI->second + // offset in symbol-table-less file
394 firstFileOffset; // add offset to first "real" file in archive
395
396 // See if the module is already loaded
397 ModuleMap::iterator MI = modules.find(fileOffset);
398 if (MI != modules.end())
399 return MI->second.first;
400
401 // Module hasn't been loaded yet, we need to load it
402 const char* modptr = base + fileOffset;
403 ArchiveMember* mbr = parseMemberHeader(modptr, mapfile->getBufferEnd(),
404 ErrMsg);
405 if (!mbr)
406 return 0;
407
408 // Now, load the bitcode module to get the Module.
409 std::string FullMemberName = archPath.str() + "(" +
410 mbr->getPath().str() + ")";
411 MemoryBuffer *Buffer =
412 MemoryBuffer::getMemBufferCopy(StringRef(mbr->getData(), mbr->getSize()),
413 FullMemberName.c_str());
414
415 Module *m = getLazyBitcodeModule(Buffer, Context, ErrMsg);
416 if (!m)
417 return 0;
418
419 modules.insert(std::make_pair(fileOffset, std::make_pair(m, mbr)));
420
421 return m;
422 }
423
424 // Look up multiple symbols in the symbol table and return a set of
425 // Modules that define those symbols.
426 bool
427 Archive::findModulesDefiningSymbols(std::set& symbols,
428 SmallVectorImpl& result,
429 std::string* error) {
430 if (!mapfile || !base) {
431 if (error)
432 *error = "Empty archive invalid for finding modules defining symbols";
433 return false;
434 }
435
436 if (symTab.empty()) {
437 // We don't have a symbol table, so we must build it now but lets also
438 // make sure that we populate the modules table as we do this to ensure
439 // that we don't load them twice when findModuleDefiningSymbol is called
440 // below.
441
442 // Get a pointer to the first file
443 const char* At = base + firstFileOffset;
444 const char* End = mapfile->getBufferEnd();
445
446 while ( At < End) {
447 // Compute the offset to be put in the symbol table
448 unsigned offset = At - base - firstFileOffset;
449
450 // Parse the file's header
451 ArchiveMember* mbr = parseMemberHeader(At, End, error);
452 if (!mbr)
453 return false;
454
455 // If it contains symbols
456 if (mbr->isBitcode()) {
457 // Get the symbols
458 std::vector symbols;
459 std::string FullMemberName = archPath.str() + "(" +
460 mbr->getPath().str() + ")";
461 Module* M =
462 GetBitcodeSymbols(At, mbr->getSize(), FullMemberName, Context,
463 symbols, error);
464
465 if (M) {
466 // Insert the module's symbols into the symbol table
467 for (std::vector::iterator I = symbols.begin(),
468 E=symbols.end(); I != E; ++I ) {
469 symTab.insert(std::make_pair(*I, offset));
470 }
471 // Insert the Module and the ArchiveMember into the table of
472 // modules.
473 modules.insert(std::make_pair(offset, std::make_pair(M, mbr)));
474 } else {
475 if (error)
476 *error = "Can't parse bitcode member: " +
477 mbr->getPath().str() + ": " + *error;
478 delete mbr;
479 return false;
480 }
481 }
482
483 // Go to the next file location
484 At += mbr->getSize();
485 if ((intptr_t(At) & 1) == 1)
486 At++;
487 }
488 }
489
490 // At this point we have a valid symbol table (one way or another) so we
491 // just use it to quickly find the symbols requested.
492
493 SmallPtrSet Added;
494 for (std::set::iterator I=symbols.begin(),
495 Next = I,
496 E=symbols.end(); I != E; I = Next) {
497 // Increment Next before we invalidate it.
498 ++Next;
499
500 // See if this symbol exists
501 Module* m = findModuleDefiningSymbol(*I,error);
502 if (!m)
503 continue;
504 bool NewMember = Added.insert(m);
505 if (!NewMember)
506 continue;
507
508 // The symbol exists, insert the Module into our result.
509 result.push_back(m);
510
511 // Remove the symbol now that its been resolved.
512 symbols.erase(I);
513 }
514 return true;
515 }
516
517 bool Archive::isBitcodeArchive() {
518 // Make sure the symTab has been loaded. In most cases this should have been
519 // done when the archive was constructed, but still, this is just in case.
520 if (symTab.empty())
521 if (!loadSymbolTable(0))
522 return false;
523
524 // Now that we know it's been loaded, return true
525 // if it has a size
526 if (symTab.size()) return true;
527
528 // We still can't be sure it isn't a bitcode archive
529 if (!loadArchive(0))
530 return false;
531
532 std::vector Modules;
533 std::string ErrorMessage;
534
535 // Scan the archive, trying to load a bitcode member. We only load one to
536 // see if this works.
537 for (iterator I = begin(), E = end(); I != E; ++I) {
538 if (!I->isBitcode())
539 continue;
540
541 std::string FullMemberName =
542 archPath.str() + "(" + I->getPath().str() + ")";
543
544 MemoryBuffer *Buffer =
545 MemoryBuffer::getMemBufferCopy(StringRef(I->getData(), I->getSize()),
546 FullMemberName.c_str());
547 Module *M = ParseBitcodeFile(Buffer, Context);
548 delete Buffer;
549 if (!M)
550 return false; // Couldn't parse bitcode, not a bitcode archive.
551 delete M;
552 return true;
553 }
554
555 return false;
556 }
+0
-429
lib/Archive/ArchiveWriter.cpp less more
None //===-- ArchiveWriter.cpp - Write LLVM archive files ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Builds up an LLVM archive file (.a) containing LLVM bitcode.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Bitcode/Archive.h"
14 #include "ArchiveInternals.h"
15 #include "llvm/ADT/OwningPtr.h"
16 #include "llvm/Bitcode/ReaderWriter.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Process.h"
21 #include "llvm/Support/Signals.h"
22 #include "llvm/Support/system_error.h"
23 #include
24 #include
25 #include
26 using namespace llvm;
27
28 // Write an integer using variable bit rate encoding. This saves a few bytes
29 // per entry in the symbol table.
30 static inline void writeInteger(unsigned num, std::ofstream& ARFile) {
31 while (1) {
32 if (num < 0x80) { // done?
33 ARFile << (unsigned char)num;
34 return;
35 }
36
37 // Nope, we are bigger than a character, output the next 7 bits and set the
38 // high bit to say that there is more coming...
39 ARFile << (unsigned char)(0x80 | ((unsigned char)num & 0x7F));
40 num >>= 7; // Shift out 7 bits now...
41 }
42 }
43
44 // Compute how many bytes are taken by a given VBR encoded value. This is needed
45 // to pre-compute the size of the symbol table.
46 static inline unsigned numVbrBytes(unsigned num) {
47
48 // Note that the following nested ifs are somewhat equivalent to a binary
49 // search. We split it in half by comparing against 2^14 first. This allows
50 // most reasonable values to be done in 2 comparisons instead of 1 for
51 // small ones and four for large ones. We expect this to access file offsets
52 // in the 2^10 to 2^24 range and symbol lengths in the 2^0 to 2^8 range,
53 // so this approach is reasonable.
54 if (num < 1<<14) {
55 if (num < 1<<7)
56 return 1;
57 else
58 return 2;
59 }
60 if (num < 1<<21)
61 return 3;
62
63 if (num < 1<<28)
64 return 4;
65 return 5; // anything >= 2^28 takes 5 bytes
66 }
67
68 // Create an empty archive.
69 Archive* Archive::CreateEmpty(const sys::Path& FilePath, LLVMContext& C) {
70 Archive* result = new Archive(FilePath, C);
71 return result;
72 }
73
74 // Fill the ArchiveMemberHeader with the information from a member. If
75 // TruncateNames is true, names are flattened to 15 chars or less. The sz field
76 // is provided here instead of coming from the mbr because the member might be
77 // stored compressed and the compressed size is not the ArchiveMember's size.
78 // Furthermore compressed files have negative size fields to identify them as
79 // compressed.
80 bool
81 Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
82 int sz, bool TruncateNames) const {
83
84 // Set the permissions mode, uid and gid
85 hdr.init();
86 char buffer[32];
87 sprintf(buffer, "%-8o", mbr.getMode());
88 memcpy(hdr.mode,buffer,8);
89 sprintf(buffer, "%-6u", mbr.getUser());
90 memcpy(hdr.uid,buffer,6);
91 sprintf(buffer, "%-6u", mbr.getGroup());
92 memcpy(hdr.gid,buffer,6);
93
94 // Set the last modification date
95 uint64_t secondsSinceEpoch = mbr.getModTime().toEpochTime();
96 sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch));
97 memcpy(hdr.date,buffer,12);
98
99 // Get rid of trailing blanks in the name
100 std::string mbrPath = mbr.getPath().str();
101 size_t mbrLen = mbrPath.length();
102 while (mbrLen > 0 && mbrPath[mbrLen-1] == ' ') {
103 mbrPath.erase(mbrLen-1,1);
104 mbrLen--;
105 }
106
107 // Set the name field in one of its various flavors.
108 bool writeLongName = false;
109 if (mbr.isStringTable()) {
110 memcpy(hdr.name,ARFILE_STRTAB_NAME,16);
111 } else if (mbr.isSVR4SymbolTable()) {
112 memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16);
113 } else if (mbr.isBSD4SymbolTable()) {
114 memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16);
115 } else if (TruncateNames) {
116 const char* nm = mbrPath.c_str();
117 unsigned len = mbrPath.length();
118 size_t slashpos = mbrPath.rfind('/');
119 if (slashpos != std::string::npos) {
120 nm += slashpos + 1;
121 len -= slashpos +1;
122 }
123 if (len > 15)
124 len = 15;
125 memcpy(hdr.name,nm,len);
126 hdr.name[len] = '/';
127 } else if (mbrPath.length() < 16 && mbrPath.find('/') == std::string::npos) {
128 memcpy(hdr.name,mbrPath.c_str(),mbrPath.length());
129 hdr.name[mbrPath.length()] = '/';
130 } else {
131 std::string nm = "#1/";
132 nm += utostr(mbrPath.length());
133 memcpy(hdr.name,nm.data(),nm.length());
134 if (sz < 0)
135 sz -= mbrPath.length();
136 else
137 sz += mbrPath.length();
138 writeLongName = true;
139 }
140
141 // Set the size field
142 if (sz < 0) {
143 buffer[0] = '-';
144 sprintf(&buffer[1],"%-9u",(unsigned)-sz);
145 } else {
146 sprintf(buffer, "%-10u", (unsigned)sz);
147 }
148 memcpy(hdr.size,buffer,10);
149
150 return writeLongName;
151 }
152
153 // Insert a file into the archive before some other member. This also takes care
154 // of extracting the necessary flags and information from the file.
155 bool
156 Archive::addFileBefore(const sys::Path& filePath, iterator where,
157 std::string* ErrMsg) {
158 bool Exists;
159 if (sys::fs::exists(filePath.str(), Exists) || !Exists) {
160 if (ErrMsg)
161 *ErrMsg = "Can not add a non-existent file to archive";
162 return true;
163 }
164
165 ArchiveMember* mbr = new ArchiveMember(this);
166
167 mbr->data = 0;
168 mbr->path = filePath;
169 const sys::FileStatus *FSInfo = mbr->path.getFileStatus(false, ErrMsg);
170 if (!FSInfo) {
171 delete mbr;
172 return true;
173 }
174 mbr->info = *FSInfo;
175
176 unsigned flags = 0;
177 bool hasSlash = filePath.str().find('/') != std::string::npos;
178 if (hasSlash)
179 flags |= ArchiveMember::HasPathFlag;
180 if (hasSlash || filePath.str().length() > 15)
181 flags |= ArchiveMember::HasLongFilenameFlag;
182
183 sys::fs::file_magic type;
184 if (sys::fs::identify_magic(mbr->path.str(), type))
185 type = sys::fs::file_magic::unknown;
186 switch (type) {
187 case sys::fs::file_magic::bitcode:
188 flags |= ArchiveMember::BitcodeFlag;
189 break;
190 default:
191 break;
192 }
193 mbr->flags = flags;
194 members.insert(where,mbr);
195 return false;
196 }
197
198 // Write one member out to the file.
199 bool
200 Archive::writeMember(
201 const ArchiveMember& member,
202 std::ofstream& ARFile,
203 bool CreateSymbolTable,
204 bool TruncateNames,
205 std::string* ErrMsg
206 ) {
207
208 unsigned filepos = ARFile.tellp();
209 filepos -= 8;
210
211 // Get the data and its size either from the
212 // member's in-memory data or directly from the file.
213 size_t fSize = member.getSize();
214 const char *data = (const char*)member.getData();
215 MemoryBuffer *mFile = 0;
216 if (!data) {
217 OwningPtr File;
218 if (error_code ec = MemoryBuffer::getFile(member.getPath().c_str(), File)) {
219 if (ErrMsg)
220 *ErrMsg = ec.message();
221 return true;
222 }
223 mFile = File.take();
224 data = mFile->getBufferStart();
225 fSize = mFile->getBufferSize();
226 }
227
228 // Now that we have the data in memory, update the
229 // symbol table if it's a bitcode file.
230 if (CreateSymbolTable && member.isBitcode()) {
231 std::vector symbols;
232 std::string FullMemberName = archPath.str() + "(" + member.getPath().str()
233 + ")";
234 Module* M =
235 GetBitcodeSymbols(data, fSize, FullMemberName, Context, symbols, ErrMsg);
236
237 // If the bitcode parsed successfully
238 if ( M ) {
239 for (std::vector::iterator SI = symbols.begin(),
240 SE = symbols.end(); SI != SE; ++SI) {
241
242 std::pair Res =
243 symTab.insert(std::make_pair(*SI,filepos));
244
245 if (Res.second) {
246 symTabSize += SI->length() +
247 numVbrBytes(SI->length()) +
248 numVbrBytes(filepos);
249 }
250 }
251 // We don't need this module any more.
252 delete M;
253 } else {
254 delete mFile;
255 if (ErrMsg)
256 *ErrMsg = "Can't parse bitcode member: " + member.getPath().str()
257 + ": " + *ErrMsg;
258 return true;
259 }
260 }
261
262 int hdrSize = fSize;
263
264 // Compute the fields of the header
265 ArchiveMemberHeader Hdr;
266 bool writeLongName = fillHeader(member,Hdr,hdrSize,TruncateNames);
267
268 // Write header to archive file
269 ARFile.write((char*)&Hdr, sizeof(Hdr));
270
271 // Write the long filename if its long
272 if (writeLongName) {
273 ARFile.write(member.getPath().str().data(),
274 member.getPath().str().length());
275 }
276
277 // Write the (possibly compressed) member's content to the file.
278 ARFile.write(data,fSize);
279
280 // Make sure the member is an even length
281 if ((ARFile.tellp() & 1) == 1)
282 ARFile << ARFILE_PAD;
283
284 // Close the mapped file if it was opened
285 delete mFile;
286 return false;
287 }
288
289 // Write the entire archive to the file specified when the archive was created.
290 // This writes to a temporary file first. Options are for creating a symbol
291 // table, flattening the file names (no directories, 15 chars max) and
292 // compressing each archive member.
293 bool
294 Archive::writeToDisk(bool CreateSymbolTable, bool TruncateNames,
295 std::string* ErrMsg)
296 {
297 // Make sure they haven't opened up the file, not loaded it,
298 // but are now trying to write it which would wipe out the file.
299 if (members.empty() && mapfile && mapfile->getBufferSize() > 8) {
300 if (ErrMsg)
301 *ErrMsg = "Can't write an archive not opened for writing";
302 return true;
303 }
304
305 // Create a temporary file to store the archive in
306 sys::Path TmpArchive = archPath;
307 if (TmpArchive.createTemporaryFileOnDisk(ErrMsg))
308 return true;
309
310 // Make sure the temporary gets removed if we crash
311 sys::RemoveFileOnSignal(TmpArchive.str());
312
313 // Create archive file for output.
314 std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
315 std::ios::binary;
316 std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode);
317
318 // Check for errors opening or creating archive file.
319 if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
320 TmpArchive.eraseFromDisk();
321 if (ErrMsg)
322 *ErrMsg = "Error opening archive file: " + archPath.str();
323 return true;
324 }
325
326 // If we're creating a symbol table, reset it now
327 if (CreateSymbolTable) {
328 symTabSize = 0;
329 symTab.clear();
330 }
331
332 // Write magic string to archive.
333 ArchiveFile << ARFILE_MAGIC;
334
335 // Loop over all member files, and write them out. Note that this also
336 // builds the symbol table, symTab.
337 for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
338 if (writeMember(*I, ArchiveFile, CreateSymbolTable,
339 TruncateNames, ErrMsg)) {
340 TmpArchive.eraseFromDisk();
341 ArchiveFile.close();
342 return true;
343 }
344 }
345
346 // Close archive file.
347 ArchiveFile.close();
348
349 // Write the symbol table
350 if (CreateSymbolTable) {
351 // At this point we have written a file that is a legal archive but it
352 // doesn't have a symbol table in it. To aid in faster reading and to
353 // ensure compatibility with other archivers we need to put the symbol
354 // table first in the file. Unfortunately, this means mapping the file
355 // we just wrote back in and copying it to the destination file.
356 sys::Path FinalFilePath = archPath;
357
358 // Map in the archive we just wrote.
359 {
360 OwningPtr arch;
361 if (error_code ec = MemoryBuffer::getFile(TmpArchive.c_str(), arch)) {
362 if (ErrMsg)
363 *ErrMsg = ec.message();
364 return true;
365 }
366 const char* base = arch->getBufferStart();
367
368 // Open another temporary file in order to avoid invalidating the
369 // mmapped data
370 if (FinalFilePath.createTemporaryFileOnDisk(ErrMsg))
371 return true;
372 sys::RemoveFileOnSignal(FinalFilePath.str());
373
374 std::ofstream FinalFile(FinalFilePath.c_str(), io_mode);
375 if (!FinalFile.is_open() || FinalFile.bad()) {
376 TmpArchive.eraseFromDisk();
377 if (ErrMsg)
378 *ErrMsg = "Error opening archive file: " + FinalFilePath.str();
379 return true;
380 }
381
382 // Write the file magic number
383 FinalFile << ARFILE_MAGIC;
384
385 // If there is a foreign symbol table, put it into the file now. Most
386 // ar(1) implementations require the symbol table to be first but llvm-ar
387 // can deal with it being after a foreign symbol table. This ensures
388 // compatibility with other ar(1) implementations as well as allowing the
389 // archive to store both native .o and LLVM .bc files, both indexed.
390 if (foreignST) {
391 if (writeMember(*foreignST, FinalFile, false, false, ErrMsg)) {
392 FinalFile.close();
393 TmpArchive.eraseFromDisk();
394 return true;
395 }
396 }
397
398 // Copy the temporary file contents being sure to skip the file's magic
399 // number.
400 FinalFile.write(base + sizeof(ARFILE_MAGIC)-1,
401 arch->getBufferSize()-sizeof(ARFILE_MAGIC)+1);
402
403 // Close up shop
404 FinalFile.close();
405 } // free arch.
406
407 // Move the final file over top of TmpArchive
408 if (FinalFilePath.renamePathOnDisk(TmpArchive, ErrMsg))
409 return true;
410 }
411
412 // Before we replace the actual archive, we need to forget all the
413 // members, since they point to data in that old archive. We need to do
414 // this because we cannot replace an open file on Windows.
415 cleanUpMemory();
416
417 if (TmpArchive.renamePathOnDisk(archPath, ErrMsg))
418 return true;
419
420 // Set correct read and write permissions after temporary file is moved
421 // to final destination path.
422 if (archPath.makeReadableOnDisk(ErrMsg))
423 return true;
424 if (archPath.makeWriteableOnDisk(ErrMsg))
425 return true;
426
427 return false;
428 }
+0
-5
lib/Archive/CMakeLists.txt less more
None add_llvm_library(LLVMArchive
1 Archive.cpp
2 ArchiveReader.cpp
3 ArchiveWriter.cpp
4 )
+0
-22
lib/Archive/LLVMBuild.txt less more
None ;===- ./lib/Archive/LLVMBuild.txt ------------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = Archive
20 parent = Libraries
21 required_libraries = BitReader Core Support
+0
-17
lib/Archive/Makefile less more
None ##===- lib/Archive/Makefile --------------------------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL = ../..
10 LIBRARYNAME = LLVMArchive
11
12 # We only want an archive so only those modules actually used by a tool are
13 # included.
14 BUILD_ARCHIVE := 1
15
16 include $(LEVEL)/Makefile.common
1313 add_subdirectory(ExecutionEngine)
1414 add_subdirectory(Target)
1515 add_subdirectory(AsmParser)
16 add_subdirectory(Archive)
1515 ;===------------------------------------------------------------------------===;
1616
1717 [common]
18 subdirectories = Analysis Archive AsmParser Bitcode CodeGen DebugInfo ExecutionEngine Linker IR IRReader MC Object Option Support TableGen Target Transforms
18 subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine Linker IR IRReader MC Object Option Support TableGen Target Transforms
1919
2020 [component_0]
2121 type = Group
99
1010 include $(LEVEL)/Makefile.config
1111
12 PARALLEL_DIRS := IR AsmParser Bitcode Archive Analysis Transforms CodeGen \
12 PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen \
1313 Target ExecutionEngine Linker MC Object Option DebugInfo \
1414 IRReader
1515
0 //===-- Archive.cpp - Generic LLVM archive functions ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the implementation of the Archive and ArchiveMember
10 // classes that is common to both reading and writing archives..
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Archive.h"
15 #include "ArchiveInternals.h"
16 #include "llvm/Bitcode/ReaderWriter.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Process.h"
21 #include "llvm/Support/system_error.h"
22 #include
23 #include
24 using namespace llvm;
25
26 // getMemberSize - compute the actual physical size of the file member as seen
27 // on disk. This isn't the size of member's payload. Use getSize() for that.
28 unsigned
29 ArchiveMember::getMemberSize() const {
30 // Basically its the file size plus the header size
31 unsigned result = info.fileSize + sizeof(ArchiveMemberHeader);
32
33 // If it has a long filename, include the name length
34 if (hasLongFilename())
35 result += path.str().length() + 1;
36
37 // If its now odd lengthed, include the padding byte
38 if (result % 2 != 0 )
39 result++;
40
41 return result;
42 }
43
44 // This default constructor is only use by the ilist when it creates its
45 // sentry node. We give it specific static values to make it stand out a bit.
46 ArchiveMember::ArchiveMember()
47 : parent(0), path("--invalid--"), flags(0), data(0)
48 {
49 info.user = sys::Process::GetCurrentUserId();
50 info.group = sys::Process::GetCurrentGroupId();
51 info.mode = 0777;
52 info.fileSize = 0;
53 info.modTime = sys::TimeValue::now();
54 }
55
56 // This is the constructor that the Archive class uses when it is building or
57 // reading an archive. It just defaults a few things and ensures the parent is
58 // set for the iplist. The Archive class fills in the ArchiveMember's data.
59 // This is required because correctly setting the data may depend on other
60 // things in the Archive.
61 ArchiveMember::ArchiveMember(Archive* PAR)
62 : parent(PAR), path(), flags(0), data(0)
63 {
64 }
65
66 // This method allows an ArchiveMember to be replaced with the data for a
67 // different file, presumably as an update to the member. It also makes sure
68 // the flags are reset correctly.
69 bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
70 bool Exists;
71 if (sys::fs::exists(newFile.str(), Exists) || !Exists) {
72 if (ErrMsg)
73 *ErrMsg = "Can not replace an archive member with a non-existent file";
74 return true;
75 }
76
77 data = 0;
78 path = newFile;
79
80 // SVR4 symbol tables have an empty name
81 if (path.str() == ARFILE_SVR4_SYMTAB_NAME)
82 flags |= SVR4SymbolTableFlag;
83 else
84 flags &= ~SVR4SymbolTableFlag;
85
86 // BSD4.4 symbol tables have a special name
87 if (path.str() == ARFILE_BSD4_SYMTAB_NAME)
88 flags |= BSD4SymbolTableFlag;
89 else
90 flags &= ~BSD4SymbolTableFlag;
91
92 // String table name
93 if (path.str() == ARFILE_STRTAB_NAME)
94 flags |= StringTableFlag;
95 else
96 flags &= ~StringTableFlag;
97
98 // If it has a slash then it has a path
99 bool hasSlash = path.str().find('/') != std::string::npos;
100 if (hasSlash)
101 flags |= HasPathFlag;
102 else
103 flags &= ~HasPathFlag;
104
105 // If it has a slash or its over 15 chars then its a long filename format
106 if (hasSlash || path.str().length() > 15)
107 flags |= HasLongFilenameFlag;
108 else
109 flags &= ~HasLongFilenameFlag;
110
111 // Get the signature and status info
112 const char* signature = (const char*) data;
113 SmallString<4> magic;
114 if (!signature) {
115 sys::fs::get_magic(path.str(), magic.capacity(), magic);
116 signature = magic.c_str();
117 const sys::FileStatus *FSinfo = path.getFileStatus(false, ErrMsg);
118 if (FSinfo)
119 info = *FSinfo;
120 else
121 return true;
122 }
123
124 // Determine what kind of file it is.
125 if (sys::fs::identify_magic(StringRef(signature, 4)) ==
126 sys::fs::file_magic::bitcode)
127 flags |= BitcodeFlag;
128 else
129 flags &= ~BitcodeFlag;
130
131 return false;
132 }
133
134 // Archive constructor - this is the only constructor that gets used for the
135 // Archive class. Everything else (default,copy) is deprecated. This just
136 // initializes and maps the file into memory, if requested.
137 Archive::Archive(const sys::Path& filename, LLVMContext& C)
138 : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
139 symTabSize(0), firstFileOffset(0), modules(), foreignST(0), Context(C) {
140 }
141
142 bool
143 Archive::mapToMemory(std::string* ErrMsg) {
144 OwningPtr File;
145 if (error_code ec = MemoryBuffer::getFile(archPath.c_str(), File)) {
146 if (ErrMsg)
147 *ErrMsg = ec.message();
148 return true;
149 }
150 mapfile = File.take();
151 base = mapfile->getBufferStart();
152 return false;
153 }
154
155 void Archive::cleanUpMemory() {
156 // Shutdown the file mapping
157 delete mapfile;
158 mapfile = 0;
159 base = 0;
160
161 // Forget the entire symbol table
162 symTab.clear();
163 symTabSize = 0;
164
165 firstFileOffset = 0;
166
167 // Free the foreign symbol table member
168 if (foreignST) {
169 delete foreignST;
170 foreignST = 0;
171 }
172
173 // Delete any Modules and ArchiveMember's we've allocated as a result of
174 // symbol table searches.
175 for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) {
176 delete I->second.first;
177 delete I->second.second;
178 }
179 }
180
181 // Archive destructor - just clean up memory
182 Archive::~Archive() {
183 cleanUpMemory();
184 }
185
186
187
188 static void getSymbols(Module*M, std::vector& symbols) {
189 // Loop over global variables
190 for (Module::global_iterator GI = M->global_begin(), GE=M->global_end(); GI != GE; ++GI)
191 if (!GI->isDeclaration() && !GI->hasLocalLinkage())
192 if (!GI->getName().empty())
193 symbols.push_back(GI->getName());
194
195 // Loop over functions
196 for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI)
197 if (!FI->isDeclaration() && !FI->hasLocalLinkage())
198 if (!FI->getName().empty())
199 symbols.push_back(FI->getName());
200
201 // Loop over aliases
202 for (Module::alias_iterator AI = M->alias_begin(), AE = M->alias_end();
203 AI != AE; ++AI) {
204 if (AI->hasName())
205 symbols.push_back(AI->getName());
206 }
207 }
208
209 // Get just the externally visible defined symbols from the bitcode
210 bool llvm::GetBitcodeSymbols(const sys::Path& fName,
211 LLVMContext& Context,
212 std::vector& symbols,
213 std::string* ErrMsg) {
214 OwningPtr Buffer;
215 if (error_code ec = MemoryBuffer::getFileOrSTDIN(fName.c_str(), Buffer)) {
216 if (ErrMsg) *ErrMsg = "Could not open file '" + fName.str() + "'" + ": "
217 + ec.message();
218 return true;
219 }
220
221 Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
222 if (!M)
223 return true;
224
225 // Get the symbols
226 getSymbols(M, symbols);
227
228 // Done with the module.
229 delete M;
230 return true;
231 }
232
233 Module*
234 llvm::GetBitcodeSymbols(const char *BufPtr, unsigned Length,
235 const std::string& ModuleID,
236 LLVMContext& Context,
237 std::vector& symbols,
238 std::string* ErrMsg) {
239 // Get the module.
240 OwningPtr Buffer(
241 MemoryBuffer::getMemBufferCopy(StringRef(BufPtr, Length),ModuleID.c_str()));
242
243 Module *M = ParseBitcodeFile(Buffer.get(), Context, ErrMsg);
244 if (!M)
245 return 0;
246
247 // Get the symbols
248 getSymbols(M, symbols);
249
250 // Done with the module. Note that it's the caller's responsibility to delete
251 // the Module.
252 return M;
253 }
0 //===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This header file declares the Archive and ArchiveMember classes that provide
10 // manipulation of LLVM Archive files. The implementation is provided by the
11 // lib/Bitcode/Archive library. This library is used to read and write
12 // archive (*.a) files that contain LLVM bitcode files (or others).
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef TOOLS_LLVM_AR_ARCHIVE_H
17 #define TOOLS_LLVM_AR_ARCHIVE_H
18
19 #include "llvm/ADT/ilist.h"
20 #include "llvm/ADT/ilist_node.h"
21 #include "llvm/Support/Path.h"
22 #include "llvm/Support/PathV1.h"
23 #include
24 #include
25
26 namespace llvm {
27 class MemoryBuffer;
28
29 // Forward declare classes
30 class Module; // From VMCore
31 class Archive; // Declared below
32 class ArchiveMemberHeader; // Internal implementation class
33 class LLVMContext; // Global data
34
35 /// This class is the main class manipulated by users of the Archive class. It
36 /// holds information about one member of the Archive. It is also the element
37 /// stored by the Archive's ilist, the Archive's main abstraction. Because of
38 /// the special requirements of archive files, users are not permitted to
39 /// construct ArchiveMember instances. You should obtain them from the methods
40 /// of the Archive class instead.
41 /// @brief This class represents a single archive member.
42 class ArchiveMember : public ilist_node {
43 /// @name Types
44 /// @{
45 public:
46 /// These flags are used internally by the archive member to specify various
47 /// characteristics of the member. The various "is" methods below provide
48 /// access to the flags. The flags are not user settable.
49 enum Flags {
50 SVR4SymbolTableFlag = 1, ///< Member is a SVR4 symbol table
51 BSD4SymbolTableFlag = 2, ///< Member is a BSD4 symbol table
52 BitcodeFlag = 4, ///< Member is bitcode
53 HasPathFlag = 8, ///< Member has a full or partial path
54 HasLongFilenameFlag = 16, ///< Member uses the long filename syntax
55 StringTableFlag = 32 ///< Member is an ar(1) format string table
56 };
57
58 /// @}
59 /// @name Accessors
60 /// @{
61 public:
62 /// @returns the parent Archive instance
63 /// @brief Get the archive associated with this member
64 Archive* getArchive() const { return parent; }
65
66 /// @returns the path to the Archive's file
67 /// @brief Get the path to the archive member
68 const sys::Path& getPath() const { return path; }
69
70 /// The "user" is the owner of the file per Unix security. This may not
71 /// have any applicability on non-Unix systems but is a required component
72 /// of the "ar" file format.
73 /// @brief Get the user associated with this archive member.
74 unsigned getUser() const { return info.getUser(); }
75
76 /// The "group" is the owning group of the file per Unix security. This
77 /// may not have any applicability on non-Unix systems but is a required
78 /// component of the "ar" file format.
79 /// @brief Get the group associated with this archive member.
80 unsigned getGroup() const { return info.getGroup(); }
81
82 /// The "mode" specifies the access permissions for the file per Unix
83 /// security. This may not have any applicability on non-Unix systems but is
84 /// a required component of the "ar" file format.
85 /// @brief Get the permission mode associated with this archive member.
86 unsigned getMode() const { return info.getMode(); }
87
88 /// This method returns the time at which the archive member was last
89 /// modified when it was not in the archive.
90 /// @brief Get the time of last modification of the archive member.
91 sys::TimeValue getModTime() const { return info.getTimestamp(); }
92
93 /// @returns the size of the archive member in bytes.
94 /// @brief Get the size of the archive member.
95 uint64_t getSize() const { return info.getSize(); }
96
97 /// This method returns the total size of the archive member as it
98 /// appears on disk. This includes the file content, the header, the
99 /// long file name if any, and the padding.
100 /// @brief Get total on-disk member size.
101 unsigned getMemberSize() const;
102
103 /// This method will return a pointer to the in-memory content of the
104 /// archive member, if it is available. If the data has not been loaded
105 /// into memory, the return value will be null.
106 /// @returns a pointer to the member's data.
107 /// @brief Get the data content of the archive member
108 const char* getData() const { return data; }
109
110 /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
111 /// @brief Determine if this member is a SVR4 symbol table.
112 bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
113
114 /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
115 /// @brief Determine if this member is a BSD4.4 symbol table.
116 bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
117
118 /// @returns true iff the archive member is the ar(1) string table
119 /// @brief Determine if this member is the ar(1) string table.
120 bool isStringTable() const { return flags&StringTableFlag; }
121
122 /// @returns true iff the archive member is a bitcode file.
123 /// @brief Determine if this member is a bitcode file.
124 bool isBitcode() const { return flags&BitcodeFlag; }
125
126 /// @returns true iff the file name contains a path (directory) component.
127 /// @brief Determine if the member has a path
128 bool hasPath() const { return flags&HasPathFlag; }
129
130 /// Long filenames are an artifact of the ar(1) file format which allows
131 /// up to sixteen characters in its header and doesn't allow a path
132 /// separator character (/). To avoid this, a "long format" member name is
133 /// allowed that doesn't have this restriction. This method determines if
134 /// that "long format" is used for this member.
135 /// @returns true iff the file name uses the long form
136 /// @brief Determine if the member has a long file name
137 bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
138
139 /// This method returns the status info (like Unix stat(2)) for the archive
140 /// member. The status info provides the file's size, permissions, and
141 /// modification time. The contents of the Path::StatusInfo structure, other
142 /// than the size and modification time, may not have utility on non-Unix
143 /// systems.
144 /// @returns the status info for the archive member
145 /// @brief Obtain the status info for the archive member
146 const sys::FileStatus &getFileStatus() const { return info; }
147
148 /// This method causes the archive member to be replaced with the contents
149 /// of the file specified by \p File. The contents of \p this will be
150 /// updated to reflect the new data from \p File. The \p File must exist and
151 /// be readable on entry to this method.
152 /// @returns true if an error occurred, false otherwise
153 /// @brief Replace contents of archive member with a new file.
154 bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
155
156 /// @}
157 /// @name Data
158 /// @{
159 private:
160 Archive* parent; ///< Pointer to parent archive
161 sys::PathWithStatus path; ///< Path of file containing the member
162 sys::FileStatus info; ///< Status info (size,mode,date)
163 unsigned flags; ///< Flags about the archive member
164 const char* data; ///< Data for the member
165
166 /// @}
167 /// @name Constructors
168 /// @{
169 public:
170 /// The default constructor is only used by the Archive's iplist when it
171 /// constructs the list's sentry node.
172 ArchiveMember();
173
174 private:
175 /// Used internally by the Archive class to construct an ArchiveMember.
176 /// The contents of the ArchiveMember are filled out by the Archive class.
177 explicit ArchiveMember(Archive *PAR);
178
179 // So Archive can construct an ArchiveMember
180 friend class llvm::Archive;
181 /// @}
182 };
183
184 /// This class defines the interface to LLVM Archive files. The Archive class
185 /// presents the archive file as an ilist of ArchiveMember objects. The members
186 /// can be rearranged in any fashion either by directly editing the ilist or by
187 /// using editing methods on the Archive class (recommended). The Archive
188 /// class also provides several ways of accessing the archive file for various
189 /// purposes such as editing and linking. Full symbol table support is provided
190 /// for loading only those files that resolve symbols. Note that read
191 /// performance of this library is _crucial_ for performance of JIT type
192 /// applications and the linkers. Consequently, the implementation of the class
193 /// is optimized for reading.
194 class Archive {
195
196 /// @name Types
197 /// @{
198 public:
199 /// This is the ilist type over which users may iterate to examine
200 /// the contents of the archive
201 /// @brief The ilist type of ArchiveMembers that Archive contains.
202 typedef iplist MembersList;
203
204 /// @brief Forward mutable iterator over ArchiveMember
205 typedef MembersList::iterator iterator;
206
207 /// @brief Forward immutable iterator over ArchiveMember
208 typedef MembersList::const_iterator const_iterator;
209
210 /// @brief Reverse mutable iterator over ArchiveMember
211 typedef std::reverse_iterator reverse_iterator;
212
213 /// @brief Reverse immutable iterator over ArchiveMember
214 typedef std::reverse_iterator const_reverse_iterator;
215
216 /// @brief The in-memory version of the symbol table
217 typedef std::map SymTabType;
218
219 /// @}
220 /// @name ilist accessor methods
221 /// @{
222 public:
223 inline iterator begin() { return members.begin(); }
224 inline const_iterator begin() const { return members.begin(); }
225 inline iterator end () { return members.end(); }
226 inline const_iterator end () const { return members.end(); }
227
228 inline reverse_iterator rbegin() { return members.rbegin(); }
229 inline const_reverse_iterator rbegin() const { return members.rbegin(); }
230 inline reverse_iterator rend () { return members.rend(); }
231 inline const_reverse_iterator rend () const { return members.rend(); }
232
233 inline size_t size() const { return members.size(); }
234 inline bool empty() const { return members.empty(); }
235 inline const ArchiveMember& front() const { return members.front(); }
236 inline ArchiveMember& front() { return members.front(); }
237 inline const ArchiveMember& back() const { return members.back(); }
238 inline ArchiveMember& back() { return members.back(); }
239
240 /// @}
241 /// @name ilist mutator methods
242 /// @{
243 public:
244 /// This method splices a \p src member from an archive (possibly \p this),
245 /// to a position just before the member given by \p dest in \p this. When
246 /// the archive is written, \p src will be written in its new location.
247 /// @brief Move a member to a new location
248 inline void splice(iterator dest, Archive& arch, iterator src)
249 { return members.splice(dest,arch.members,src); }
250
251 /// This method erases a \p target member from the archive. When the
252 /// archive is written, it will no longer contain \p target. The associated
253 /// ArchiveMember is deleted.
254 /// @brief Erase a member.
255 inline iterator erase(iterator target) { return members.erase(target); }
256
257 /// @}
258 /// @name Constructors
259 /// @{
260 public:
261 /// Create an empty archive file and associate it with the \p Filename. This
262 /// method does not actually create the archive disk file. It creates an
263 /// empty Archive object. If the writeToDisk method is called, the archive
264 /// file \p Filename will be created at that point, with whatever content
265 /// the returned Archive object has at that time.
266 /// @returns An Archive* that represents the new archive file.
267 /// @brief Create an empty Archive.
268 static Archive* CreateEmpty(
269 const sys::Path& Filename,///< Name of the archive to (eventually) create.
270 LLVMContext& C ///< Context to use for global information
271 );
272
273 /// Open an existing archive and load its contents in preparation for
274 /// editing. After this call, the member ilist is completely populated based
275 /// on the contents of the archive file. You should use this form of open if
276 /// you intend to modify the archive or traverse its contents (e.g. for
277 /// printing).
278 /// @brief Open and load an archive file
279 static Archive* OpenAndLoad(
280 const sys::Path& filePath, ///< The file path to open and load
281 LLVMContext& C, ///< The context to use for global information
282 std::string* ErrorMessage ///< An optional error string
283 );
284
285 /// This method opens an existing archive file from \p Filename and reads in
286 /// its symbol table without reading in any of the archive's members. This
287 /// reduces both I/O and cpu time in opening the archive if it is to be used
288 /// solely for symbol lookup (e.g. during linking). The \p Filename must
289 /// exist and be an archive file or an error will be returned. This form
290 /// of opening the archive is intended for read-only operations that need to
291 /// locate members via the symbol table for link editing. Since the archve
292 /// members are not read by this method, the archive will appear empty upon
293 /// return. If editing operations are performed on the archive, they will
294 /// completely replace the contents of the archive! It is recommended that
295 /// if this form of opening the archive is used that only the symbol table
296 /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
297 /// findModulesDefiningSymbols) be used.
298 /// @returns an Archive* that represents the archive file, or null on error.
299 /// @brief Open an existing archive and load its symbols.
300 static Archive* OpenAndLoadSymbols(
301 const sys::Path& Filename, ///< Name of the archive file to open
302 LLVMContext& C, ///< The context to use for global info
303 std::string* ErrorMessage=0 ///< An optional error string
304 );
305
306 /// This destructor cleans up the Archive object, releases all memory, and
307 /// closes files. It does nothing with the archive file on disk. If you
308 /// haven't used the writeToDisk method by the time the destructor is
309 /// called, all changes to the archive will be lost.
310 /// @brief Destruct in-memory archive
311 ~Archive();
312
313 /// @}
314 /// @name Accessors
315 /// @{
316 public:
317 /// @returns the path to the archive file.
318 /// @brief Get the archive path.
319 const sys::Path& getPath() { return archPath; }
320
321 /// This method is provided so that editing methods can be invoked directly
322 /// on the Archive's iplist of ArchiveMember. However, it is recommended
323 /// that the usual STL style iterator interface be used instead.
324 /// @returns the iplist of ArchiveMember
325 /// @brief Get the iplist of the members
326 MembersList& getMembers() { return members; }
327
328 /// This method allows direct query of the Archive's symbol table. The
329 /// symbol table is a std::map of std::string (the symbol) to unsigned (the
330 /// file offset). Note that for efficiency reasons, the offset stored in
331 /// the symbol table is not the actual offset. It is the offset from the
332 /// beginning of the first "real" file member (after the symbol table). Use
333 /// the getFirstFileOffset() to obtain that offset and add this value to the
334 /// offset in the symbol table to obtain the real file offset. Note that
335 /// there is purposefully no interface provided by Archive to look up
336 /// members by their offset. Use the findModulesDefiningSymbols and
337 /// findModuleDefiningSymbol methods instead.
338 /// @returns the Archive's symbol table.
339 /// @brief Get the archive's symbol table
340 const SymTabType& getSymbolTable() { return symTab; }
341
342 /// This method returns the offset in the archive file to the first "real"
343 /// file member. Archive files, on disk, have a signature and might have a
344 /// symbol table that precedes the first actual file member. This method
345 /// allows you to determine what the size of those fields are.
346 /// @returns the offset to the first "real" file member in the archive.
347 /// @brief Get the offset to the first "real" file member in the archive.
348 unsigned getFirstFileOffset() { return firstFileOffset; }
349
350 /// This method will scan the archive for bitcode modules, interpret them
351 /// and return a vector of the instantiated modules in \p Modules. If an
352 /// error occurs, this method will return true. If \p ErrMessage is not null
353 /// and an error occurs, \p *ErrMessage will be set to a string explaining
354 /// the error that occurred.
355 /// @returns true if an error occurred
356 /// @brief Instantiate all the bitcode modules located in the archive
357 bool getAllModules(std::vector& Modules, std::string* ErrMessage);
358
359 /// This accessor looks up the \p symbol in the archive's symbol table and
360 /// returns the associated module that defines that symbol. This method can
361 /// be called as many times as necessary. This is handy for linking the
362 /// archive into another module based on unresolved symbols. Note that the
363 /// Module returned by this accessor should not be deleted by the caller. It
364 /// is managed internally by the Archive class. It is possible that multiple
365 /// calls to this accessor will return the same Module instance because the
366 /// associated module defines multiple symbols.
367 /// @returns The Module* found or null if the archive does not contain a
368 /// module that defines the \p symbol.
369 /// @brief Look up a module by symbol name.
370 Module* findModuleDefiningSymbol(
371 const std::string& symbol, ///< Symbol to be sought
372 std::string* ErrMessage ///< Error message storage, if non-zero
373 );
374
375 /// This method is similar to findModuleDefiningSymbol but allows lookup of
376 /// more than one symbol at a time. If \p symbols contains a list of
377 /// undefined symbols in some module, then calling this method is like
378 /// making one complete pass through the archive to resolve symbols but is
379 /// more efficient than looking at the individual members. Note that on
380 /// exit, the symbols resolved by this method will be removed from \p
381 /// symbols to ensure they are not re-searched on a subsequent call. If
382 /// you need to retain the list of symbols, make a copy.
383 /// @brief Look up multiple symbols in the archive.
384 bool findModulesDefiningSymbols(
385 std::set& symbols, ///< Symbols to be sought
386 SmallVectorImpl& modules, ///< The modules matching \p symbols
387 std::string* ErrMessage ///< Error msg storage, if non-zero
388 );
389
390 /// This method determines whether the archive is a properly formed llvm
391 /// bitcode archive. It first makes sure the symbol table has been loaded
392 /// and has a non-zero size. If it does, then it is an archive. If not,
393 /// then it tries to load all the bitcode modules of the archive. Finally,
394 /// it returns whether it was successful.
395 /// @returns true if the archive is a proper llvm bitcode archive
396 /// @brief Determine whether the archive is a proper llvm bitcode archive.
397 bool isBitcodeArchive();
398
399 /// @}
400 /// @name Mutators
401 /// @{
402 public:
403 /// This method is the only way to get the archive written to disk. It
404 /// creates or overwrites the file specified when \p this was created
405 /// or opened. The arguments provide options for writing the archive. If
406 /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
407 /// and a symbol table of the externally visible function and global
408 /// variable names is created. If \p TruncateNames is true, the names of the
409 /// archive members will have their path component stripped and the file
410 /// name will be truncated at 15 characters. If \p Compress is specified,
411 /// all archive members will be compressed before being written. If
412 /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
413 /// @returns true if an error occurred, \p error set to error message;
414 /// returns false if the writing succeeded.
415 /// @brief Write (possibly modified) archive contents to disk
416 bool writeToDisk(
417 bool CreateSymbolTable=false, ///< Create Symbol table
418 bool TruncateNames=false, ///< Truncate the filename to 15 chars
419 std::string* ErrMessage=0 ///< If non-null, where error msg is set
420 );
421
422 /// This method adds a new file to the archive. The \p filename is examined
423 /// to determine just enough information to create an ArchiveMember object
424 /// which is then inserted into the Archive object's ilist at the location
425 /// given by \p where.
426 /// @returns true if an error occurred, false otherwise
427 /// @brief Add a file to the archive.
428 bool addFileBefore(
429 const sys::Path& filename, ///< The file to be added
430 iterator where, ///< Insertion point
431 std::string* ErrMsg ///< Optional error message location
432 );
433
434 /// @}
435 /// @name Implementation
436 /// @{
437 protected:
438 /// @brief Construct an Archive for \p filename and optionally map it
439 /// into memory.
440 explicit Archive(const sys::Path& filename, LLVMContext& C);
441
442 /// @returns A fully populated ArchiveMember or 0 if an error occurred.
443 /// @brief Parse the header of a member starting at \p At
444 ArchiveMember* parseMemberHeader(
445 const char*&At, ///< The pointer to the location we're parsing
446 const char*End, ///< The pointer to the end of the archive
447 std::string* error ///< Optional error message catcher
448 );
449
450 /// @param ErrMessage Set to address of a std::string to get error messages
451 /// @returns false on error
452 /// @brief Check that the archive signature is correct
453 bool checkSignature(std::string* ErrMessage);
454
455 /// @param ErrMessage Set to address of a std::string to get error messages
456 /// @returns false on error
457 /// @brief Load the entire archive.
458 bool loadArchive(std::string* ErrMessage);
459
460 /// @param ErrMessage Set to address of a std::string to get error messages
461 /// @returns false on error
462 /// @brief Load just the symbol table.
463 bool loadSymbolTable(std::string* ErrMessage);
464
465 /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
466 /// false, otherwise true. If an error occurs and error is non-null then
467 /// it will be set to an error message.
468 /// @returns false if writing member succeeded,
469 /// returns true if writing member failed, \p error set to error message.
470 bool writeMember(
471 const ArchiveMember& member, ///< The member to be written
472 std::ofstream& ARFile, ///< The file to write member onto
473 bool CreateSymbolTable, ///< Should symbol table be created?
474 bool TruncateNames, ///< Should names be truncated to 11 chars?
475 std::string* ErrMessage ///< If non-null, place were error msg is set
476 );
477
478 /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
479 bool fillHeader(const ArchiveMember&mbr,
480 ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
481
482 /// @brief Maps archive into memory
483 bool mapToMemory(std::string* ErrMsg);
484
485 /// @brief Frees all the members and unmaps the archive file.
486 void cleanUpMemory();
487
488 /// This type is used to keep track of bitcode modules loaded from the
489 /// symbol table. It maps the file offset to a pair that consists of the
490 /// associated ArchiveMember and the Module.
491 /// @brief Module mapping type
492 typedef std::map >
493 ModuleMap;
494
495
496 /// @}
497 /// @name Data
498 /// @{
499 protected:
500 sys::Path archPath; ///< Path to the archive file we read/write
501 MembersList members; ///< The ilist of ArchiveMember
502 MemoryBuffer *mapfile; ///< Raw Archive contents mapped into memory
503 const char* base; ///< Base of the memory mapped file data
504 SymTabType symTab; ///< The symbol table
505 std::string strtab; ///< The string table for long file names
506 unsigned symTabSize; ///< Size in bytes of symbol table
507 unsigned firstFileOffset; ///< Offset to first normal file.
508 ModuleMap modules; ///< The modules loaded via symbol lookup.
509 ArchiveMember* foreignST; ///< This holds the foreign symbol table.
510 LLVMContext& Context; ///< This holds global data.
511 /// @}
512 /// @name Hidden
513 /// @{
514 private:
515 Archive() LLVM_DELETED_FUNCTION;
516 Archive(const Archive&) LLVM_DELETED_FUNCTION;
517 Archive& operator=(const Archive&) LLVM_DELETED_FUNCTION;
518 /// @}
519 };
520
521 } // End llvm namespace
522
523 #endif
0 //===-- lib/Archive/ArchiveInternals.h -------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Internal implementation header for LLVM Archive files.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef TOOLS_LLVM_AR_ARCHIVEINTERNALS_H
14 #define TOOLS_LLVM_AR_ARCHIVEINTERNALS_H
15
16 #include "Archive.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/TimeValue.h"
19 #include
20
21 #define ARFILE_MAGIC "!\n" ///< magic string
22 #define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string
23 #define ARFILE_SVR4_SYMTAB_NAME "/ " ///< SVR4 symtab entry name
24 #define ARFILE_BSD4_SYMTAB_NAME "__.SYMDEF SORTED" ///< BSD4 symtab entry name
25 #define ARFILE_STRTAB_NAME "// " ///< Name of string table
26 #define ARFILE_PAD "\n" ///< inter-file align padding
27 #define ARFILE_MEMBER_MAGIC "`\n" ///< fmag field magic #
28
29 namespace llvm {
30
31 class LLVMContext;
32
33 /// The ArchiveMemberHeader structure is used internally for bitcode
34 /// archives.
35 /// The header precedes each file member in the archive. This structure is
36 /// defined using character arrays for direct and correct interpretation
37 /// regardless of the endianess of the machine that produced it.
38 /// @brief Archive File Member Header
39 class ArchiveMemberHeader {
40 /// @name Data
41 /// @{
42 public:
43 char name[16]; ///< Name of the file member.
44 char date[12]; ///< File date, decimal seconds since Epoch
45 char uid[6]; ///< user id in ASCII decimal
46 char gid[6]; ///< group id in ASCII decimal
47 char mode[8]; ///< file mode in ASCII octal
48 char size[10]; ///< file size in ASCII decimal
49 char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR
50
51 /// @}
52 /// @name Methods
53 /// @{
54 public:
55 void init() {
56 memset(name,' ',16);
57 memset(date,' ',12);
58 memset(uid,' ',6);
59 memset(gid,' ',6);
60 memset(mode,' ',8);
61 memset(size,' ',10);
62 fmag[0] = '`';
63 fmag[1] = '\n';
64 }
65
66 bool checkSignature() const {
67 return 0 == memcmp(fmag, ARFILE_MEMBER_MAGIC,2);
68 }
69 };
70
71 // Get just the externally visible defined symbols from the bitcode
72 bool GetBitcodeSymbols(const sys::Path& fName,
73 LLVMContext& Context,
74 std::vector& symbols,
75 std::string* ErrMsg);
76
77 Module* GetBitcodeSymbols(const char *Buffer, unsigned Length,
78 const std::string& ModuleID,
79 LLVMContext& Context,
80 std::vector& symbols,
81 std::string* ErrMsg);
82 }
83
84 #endif
85
86 // vim: sw=2 ai
0 //===-- ArchiveReader.cpp - Read LLVM archive files -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Builds up standard unix archive files (.a) containing LLVM bitcode.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "Archive.h"
14 #include "ArchiveInternals.h"
15 #include "llvm/ADT/OwningPtr.h"
16 #include "llvm/ADT/SmallPtrSet.h"
17 #include "llvm/Bitcode/ReaderWriter.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/MemoryBuffer.h"
21 #include
22 #include
23 using namespace llvm;
24
25 /// Read a variable-bit-rate encoded unsigned integer
26 static inline unsigned readInteger(const char*&At, const char*End) {
27 unsigned Shift = 0;
28 unsigned Result = 0;
29
30 do {
31 if (At == End)
32 return Result;
33 Result |= (unsigned)((*At++) & 0x7F) << Shift;
34 Shift += 7;
35 } while (At[-1] & 0x80);
36 return Result;
37 }
38
39 // This member parses an ArchiveMemberHeader that is presumed to be pointed to
40 // by At. The At pointer is updated to the byte just after the header, which
41 // can be variable in size.
42 ArchiveMember*
43 Archive::parseMemberHeader(const char*& At, const char* End, std::string* error)
44 {
45 if (At + sizeof(ArchiveMemberHeader) >= End) {
46 if (error)
47 *error = "Unexpected end of file";
48 return 0;
49 }
50
51 // Cast archive member header
52 const ArchiveMemberHeader* Hdr = (const ArchiveMemberHeader*)At;
53 At += sizeof(ArchiveMemberHeader);
54
55 int flags = 0;
56 int MemberSize = atoi(Hdr->size);
57 assert(MemberSize >= 0);
58
59 // Check the size of the member for sanity
60 if (At + MemberSize > End) {
61 if (error)
62 *error = "invalid member length in archive file";
63 return 0;
64 }
65
66 // Check the member signature
67 if (!Hdr->checkSignature()) {
68 if (error)
69 *error = "invalid file member signature";
70 return 0;
71 }
72
73 // Convert and check the member name
74 // The empty name ( '/' and 15 blanks) is for a foreign (non-LLVM) symbol
75 // table. The special name "//" and 14 blanks is for a string table, used
76 // for long file names. This library doesn't generate either of those but
77 // it will accept them. If the name starts with #1/ and the remainder is
78 // digits, then those digits specify the length of the name that is
79 // stored immediately following the header. Anything else is a regular, short
80 // filename that is terminated with a '/' and blanks.
81
82 std::string pathname;
83 switch (Hdr->name[0]) {
84 case '#':
85 if (Hdr->name[1] == '1' && Hdr->name[2] == '/') {
86 if (isdigit(Hdr->name[3])) {
87 unsigned len = atoi(&Hdr->name[3]);
88 const char *nulp = (const char *)memchr(At, '\0', len);
89 pathname.assign(At, nulp != 0 ? (uintptr_t)(nulp - At) : len);
90 At += len;
91 MemberSize -= len;
92 flags |= ArchiveMember::HasLongFilenameFlag;
93 } else {
94 if (error)
95 *error = "invalid long filename";
96 return 0;
97 }
98 }
99 break;
100 case '/':
101 if (Hdr->name[1]== '/') {
102 if (0 == memcmp(Hdr->name, ARFILE_STRTAB_NAME, 16)) {
103 pathname.assign(ARFILE_STRTAB_NAME);
104 flags |= ArchiveMember::StringTableFlag;
105 } else {
106 if (error)
107 *error = "invalid string table name";
108 return 0;
109 }
110 } else if (Hdr->name[1] == ' ') {
111 if (0 == memcmp(Hdr->name, ARFILE_SVR4_SYMTAB_NAME, 16)) {
112 pathname.assign(ARFILE_SVR4_SYMTAB_NAME);
113 flags |= ArchiveMember::SVR4SymbolTableFlag;
114 } else {
115 if (error)
116 *error = "invalid SVR4 symbol table name";
117 return 0;
118 }
119 } else if (isdigit(Hdr->name[1])) {
120 unsigned index = atoi(&Hdr->name[1]);
121 if (index < strtab.length()) {
122 const char* namep = strtab.c_str() + index;
123 const char* endp = strtab.c_str() + strtab.length();
124 const char* p = namep;
125 const char* last_p = p;
126 while (p < endp) {
127 if (*p == '\n' && *last_p == '/') {
128 pathname.assign(namep, last_p - namep);
129 flags |= ArchiveMember::HasLongFilenameFlag;
130 break;
131 }
132 last_p = p;
133 p++;
134 }
135 if (p >= endp) {
136 if (error)
137 *error = "missing name terminator in string table";
138 return 0;
139 }
140 } else {
141 if (error)
142 *error = "name index beyond string table";
143 return 0;
144 }
145 }
146 break;
147 case '_':
148 if (Hdr->name[1] == '_' &&
149 (0 == memcmp(Hdr->name, ARFILE_BSD4_SYMTAB_NAME, 16))) {
150 pathname.assign(ARFILE_BSD4_SYMTAB_NAME);
151 flags |= ArchiveMember::BSD4SymbolTableFlag;
152 break;
153 }
154 /* FALL THROUGH */
155
156 default:
157 const char* slash = (const char*) memchr(Hdr->name, '/', 16);
158 if (slash == 0)
159 slash = Hdr->name + 16;
160 pathname.assign(Hdr->name, slash - Hdr->name);
161 break;
162 }
163
164 // Determine if this is a bitcode file
165 if (sys::fs::identify_magic(StringRef(At, 4)) ==
166 sys::fs::file_magic::bitcode)
167 flags |= ArchiveMember::BitcodeFlag;
168 else
169 flags &= ~ArchiveMember::BitcodeFlag;
170
171 // Instantiate the ArchiveMember to be filled
172 ArchiveMember* member = new ArchiveMember(this);
173
174 // Fill in fields of the ArchiveMember
175 member->parent = this;
176 member->path.set(pathname);
177 member->info.fileSize = MemberSize;
178 member->info.modTime.fromEpochTime(atoi(Hdr->date));
179 unsigned int mode;
180 sscanf(Hdr->mode, "%o", &mode);
181 member->info.mode = mode;
182 member->info.user = atoi(Hdr->uid);
183 member->info.group = atoi(Hdr->gid);
184 member->flags = flags;
185 member->data = At;
186
187 return member;
188 }
189
190 bool
191 Archive::checkSignature(std::string* error) {
192 // Check the magic string at file's header
193 if (mapfile->getBufferSize() < 8 || memcmp(base, ARFILE_MAGIC, 8)) {
194 if (error)
195 *error = "invalid signature for an archive file";
196 return false;
197 }
198 return true;
199 }
200
201 // This function loads the entire archive and fully populates its ilist with
202 // the members of the archive file. This is typically used in preparation for
203 // editing the contents of the archive.
204 bool
205 Archive::loadArchive(std::string* error) {
206
207 // Set up parsing
208 members.clear();
209 symTab.clear();
210 const char *At = base;
211 const char *End = mapfile->getBufferEnd();
212
213 if (!checkSignature(error))
214 return false;
215
216 At += 8; // Skip the magic string.
217
218 bool foundFirstFile = false;
219 while (At < End) {
220 // parse the member header
221 const char* Save = At;
222 ArchiveMember* mbr = parseMemberHeader(At, End, error);
223 if (!mbr)
224 return false;
225
226 // check if this is the foreign symbol table
227 if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
228 // We just save this but don't do anything special
229 // with it. It doesn't count as the "first file".
230 if (foreignST) {
231 // What? Multiple foreign symbol tables? Just chuck it
232 // and retain the last one found.
233 delete foreignST;
234 }
235 foreignST = mbr;
236 At += mbr->getSize();
237 if ((intptr_t(At) & 1) == 1)
238 At++;
239 } else if (mbr->isStringTable()) {
240 // Simply suck the entire string table into a string
241 // variable. This will be used to get the names of the
242 // members that use the "/ddd" format for their names
243 // (SVR4 style long names).
244 strtab.assign(At, mbr->getSize());
245 At += mbr->getSize();
246 if ((intptr_t(At) & 1) == 1)
247 At++;
248 delete mbr;
249 } else {
250 // This is just a regular file. If its the first one, save its offset.
251 // Otherwise just push it on the list and move on to the next file.
252 if (!foundFirstFile) {
253 firstFileOffset = Save - base;
254 foundFirstFile = true;
255 }
256 members.push_back(mbr);
257 At += mbr->getSize();
258 if ((intptr_t(At) & 1) == 1)
259 At++;
260 }
261 }
262 return true;
263 }
264
265 // Open and completely load the archive file.
266 Archive*
267 Archive::OpenAndLoad(const sys::Path& File, LLVMContext& C,
268 std::string* ErrorMessage) {
269 OwningPtr result ( new Archive(File, C));
270 if (result->mapToMemory(ErrorMessage))
271 return NULL;
272 if (!result->loadArchive(ErrorMessage))
273 return NULL;
274 return result.take();
275 }
276
277 // Get all the bitcode modules from the archive
278 bool
279 Archive::getAllModules(std::vector& Modules,
280 std::string* ErrMessage) {
281
282 for (iterator I=begin(), E=end(); I != E; ++I) {
283 if (I->isBitcode()) {
284 std::string FullMemberName = archPath.str() +
285 "(" + I->getPath().str() + ")";
286 MemoryBuffer *Buffer =
287 MemoryBuffer::getMemBufferCopy(StringRef(I->getData(), I->getSize()),
288 FullMemberName.c_str());
289
290 Module *M = ParseBitcodeFile(Buffer, Context, ErrMessage);
291 delete Buffer;
292 if (!M)
293 return true;
294
295 Modules.push_back(M);
296 }
297 }
298 return false;
299 }
300
301 // Load just the symbol table from the archive file
302 bool
303 Archive::loadSymbolTable(std::string* ErrorMsg) {
304
305 // Set up parsing
306 members.clear();
307 symTab.clear();
308 const char *At = base;
309 const char *End = mapfile->getBufferEnd();
310
311 // Make sure we're dealing with an archive
312 if (!checkSignature(ErrorMsg))
313 return false;
314
315 At += 8; // Skip signature
316
317 // Parse the first file member header
318 const char* FirstFile = At;
319 ArchiveMember* mbr = parseMemberHeader(At, End, ErrorMsg);
320 if (!mbr)
321 return false;
322
323 if (mbr->isSVR4SymbolTable() || mbr->isBSD4SymbolTable()) {
324 // Skip the foreign symbol table, we don't do anything with it
325 At += mbr->getSize();
326 if ((intptr_t(At) & 1) == 1)
327 At++;
328 delete mbr;
329
330 // Read the next one
331 FirstFile = At;
332 mbr = parseMemberHeader(At, End, ErrorMsg);
333 if (!mbr) {
334 delete mbr;
335 return false;
336 }
337 }
338
339 if (mbr->isStringTable()) {
340 // Process the string table entry
341 strtab.assign((const char*)mbr->getData(), mbr->getSize());
342 At += mbr->getSize();
343 if ((intptr_t(At) & 1) == 1)
344 At++;
345 delete mbr;
346 // Get the next one
347 FirstFile = At;
348 mbr = parseMemberHeader(At, End, ErrorMsg);
349 if (!mbr) {
350 delete mbr;
351 return false;
352 }
353 }
354
355 // There's no symbol table in the file. We have to rebuild it from scratch
356 // because the intent of this method is to get the symbol table loaded so
357 // it can be searched efficiently.
358 // Add the member to the members list
359 members.push_back(mbr);
360
361 firstFileOffset = FirstFile - base;
362 return true;
363 }
364
365 // Open the archive and load just the symbol tables
366 Archive* Archive::OpenAndLoadSymbols(const sys::Path& File,
367 LLVMContext& C,
368 std::string* ErrorMessage) {
369 OwningPtr result ( new Archive(File, C) );
370 if (result->mapToMemory(ErrorMessage))
371 return NULL;
372 if (!result->loadSymbolTable(ErrorMessage))
373 return NULL;
374 return result.take();
375 }
376
377 // Look up one symbol in the symbol table and return the module that defines
378 // that symbol.
379 Module*
380 Archive::findModuleDefiningSymbol(const std::string& symbol,
381 std::string* ErrMsg) {
382 SymTabType::iterator SI = symTab.find(symbol);
383 if (SI == symTab.end())
384 return 0;
385
386 // The symbol table was previously constructed assuming that the members were
387 // written without the symbol table header. Because VBR encoding is used, the
388 // values could not be adjusted to account for the offset of the symbol table
389 // because that could affect the size of the symbol table due to VBR encoding.
390 // We now have to account for this by adjusting the offset by the size of the
391 // symbol table and its header.
392 unsigned fileOffset =
393 SI->second + // offset in symbol-table-less file
394 firstFileOffset; // add offset to first "real" file in archive
395
396 // See if the module is already loaded
397 ModuleMap::iterator MI = modules.find(fileOffset);
398 if (MI != modules.end())
399 return MI->second.first;
400
401 // Module hasn't been loaded yet, we need to load it
402 const char* modptr = base + fileOffset;
403 ArchiveMember* mbr = parseMemberHeader(modptr, mapfile->getBufferEnd(),
404 ErrMsg);
405 if (!mbr)
406 return 0;
407
408 // Now, load the bitcode module to get the Module.
409 std::string FullMemberName = archPath.str() + "(" +
410 mbr->getPath().str() + ")";
411 MemoryBuffer *Buffer =
412 MemoryBuffer::getMemBufferCopy(StringRef(mbr->getData(), mbr->getSize()),
413 FullMemberName.c_str());
414
415 Module *m = getLazyBitcodeModule(Buffer, Context, ErrMsg);
416 if (!m)
417 return 0;
418
419 modules.insert(std::make_pair(fileOffset, std::make_pair(m, mbr)));
420
421 return m;
422 }
423
424 // Look up multiple symbols in the symbol table and return a set of
425 // Modules that define those symbols.
426 bool
427 Archive::findModulesDefiningSymbols(std::set& symbols,
428 SmallVectorImpl& result,
429 std::string* error) {
430 if (!mapfile || !base) {
431 if (error)
432 *error = "Empty archive invalid for finding modules defining symbols";
433 return false;
434 }
435
436 if (symTab.empty()) {
437 // We don't have a symbol table, so we must build it now but lets also
438 // make sure that we populate the modules table as we do this to ensure
439 // that we don't load them twice when findModuleDefiningSymbol is called
440 // below.
441
442 // Get a pointer to the first file
443 const char* At = base + firstFileOffset;
444 const char* End = mapfile->getBufferEnd();
445
446 while ( At < End) {
447 // Compute the offset to be put in the symbol table
448 unsigned offset = At - base - firstFileOffset;
449
450 // Parse the file's header
451 ArchiveMember* mbr = parseMemberHeader(At, End, error);
452 if (!mbr)
453 return false;
454
455 // If it contains symbols
456 if (mbr->isBitcode()) {
457 // Get the symbols
458 std::vector symbols;
459 std::string FullMemberName = archPath.str() + "(" +
460 mbr->getPath().str() + ")";
461 Module* M =
462 GetBitcodeSymbols(At, mbr->getSize(), FullMemberName, Context,
463 symbols, error);
464
465 if (M) {
466 // Insert the module's symbols into the symbol table
467 for (std::vector::iterator I = symbols.begin(),
468 E=symbols.end(); I != E; ++I ) {
469 symTab.insert(std::make_pair(*I, offset));
470 }
471 // Insert the Module and the ArchiveMember into the table of
472 // modules.
473 modules.insert(std::make_pair(offset, std::make_pair(M, mbr)));
474 } else {
475 if (error)
476 *error = "Can't parse bitcode member: " +
477 mbr->getPath().str() + ": " + *error;
478 delete mbr;
479 return false;
480 }
481 }
482
483 // Go to the next file location
484 At += mbr->getSize();
485 if ((intptr_t(At) & 1) == 1)
486 At++;
487 }
488 }
489
490 // At this point we have a valid symbol table (one way or another) so we
491 // just use it to quickly find the symbols requested.
492
493 SmallPtrSet Added;
494 for (std::set::iterator I=symbols.begin(),
495 Next = I,
496 E=symbols.end(); I != E; I = Next) {
497 // Increment Next before we invalidate it.
498 ++Next;
499
500 // See if this symbol exists
501 Module* m = findModuleDefiningSymbol(*I,error);
502 if (!m)
503 continue;
504 bool NewMember = Added.insert(m);
505 if (!NewMember)
506 continue;
507
508 // The symbol exists, insert the Module into our result.
509 result.push_back(m);
510
511 // Remove the symbol now that its been resolved.
512 symbols.erase(I);
513 }
514 return true;
515 }
516
517 bool Archive::isBitcodeArchive() {
518 // Make sure the symTab has been loaded. In most cases this should have been
519 // done when the archive was constructed, but still, this is just in case.
520 if (symTab.empty())
521 if (!loadSymbolTable(0))
522 return false;
523
524 // Now that we know it's been loaded, return true
525 // if it has a size
526 if (symTab.size()) return true;
527
528 // We still can't be sure it isn't a bitcode archive
529 if (!loadArchive(0))
530 return false;
531
532 std::vector Modules;
533 std::string ErrorMessage;
534
535 // Scan the archive, trying to load a bitcode member. We only load one to
536 // see if this works.
537 for (iterator I = begin(), E = end(); I != E; ++I) {
538 if (!I->isBitcode())
539 continue;
540
541 std::string FullMemberName =
542 archPath.str() + "(" + I->getPath().str() + ")";
543
544 MemoryBuffer *Buffer =
545 MemoryBuffer::getMemBufferCopy(StringRef(I->getData(), I->getSize()),
546 FullMemberName.c_str());
547 Module *M = ParseBitcodeFile(Buffer, Context);
548 delete Buffer;
549 if (!M)
550 return false; // Couldn't parse bitcode, not a bitcode archive.
551 delete M;
552 return true;
553 }
554
555 return false;
556 }
0 //===-- ArchiveWriter.cpp - Write LLVM archive files ----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Builds up an LLVM archive file (.a) containing LLVM bitcode.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "Archive.h"
14 #include "ArchiveInternals.h"
15 #include "llvm/ADT/OwningPtr.h"
16 #include "llvm/Bitcode/ReaderWriter.h"
17 #include "llvm/IR/Module.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/Support/Process.h"
21 #include "llvm/Support/Signals.h"
22 #include "llvm/Support/system_error.h"
23 #include
24 #include
25 #include
26 using namespace llvm;
27
28 // Write an integer using variable bit rate encoding. This saves a few bytes
29 // per entry in the symbol table.
30 static inline void writeInteger(unsigned num, std::ofstream& ARFile) {
31 while (1) {
32 if (num < 0x80) { // done?
33 ARFile << (unsigned char)num;
34 return;
35 }
36
37 // Nope, we are bigger than a character, output the next 7 bits and set the
38 // high bit to say that there is more coming...
39 ARFile << (unsigned char)(0x80 | ((unsigned char)num & 0x7F));
40 num >>= 7; // Shift out 7 bits now...
41 }
42 }
43
44 // Compute how many bytes are taken by a given VBR encoded value. This is needed
45 // to pre-compute the size of the symbol table.
46 static inline unsigned numVbrBytes(unsigned num) {
47
48 // Note that the following nested ifs are somewhat equivalent to a binary
49 // search. We split it in half by comparing against 2^14 first. This allows
50 // most reasonable values to be done in 2 comparisons instead of 1 for
51 // small ones and four for large ones. We expect this to access file offsets
52 // in the 2^10 to 2^24 range and symbol lengths in the 2^0 to 2^8 range,
53 // so this approach is reasonable.
54 if (num < 1<<14) {
55 if (num < 1<<7)
56 return 1;
57 else
58 return 2;
59 }
60 if (num < 1<<21)
61 return 3;
62
63 if (num < 1<<28)
64 return 4;
65 return 5; // anything >= 2^28 takes 5 bytes
66 }
67
68 // Create an empty archive.
69 Archive* Archive::CreateEmpty(const sys::Path& FilePath, LLVMContext& C) {
70 Archive* result = new Archive(FilePath, C);
71 return result;
72 }
73
74 // Fill the ArchiveMemberHeader with the information from a member. If
75 // TruncateNames is true, names are flattened to 15 chars or less. The sz field
76 // is provided here instead of coming from the mbr because the member might be
77 // stored compressed and the compressed size is not the ArchiveMember's size.
78 // Furthermore compressed files have negative size fields to identify them as
79 // compressed.
80 bool
81 Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
82 int sz, bool TruncateNames) const {
83
84 // Set the permissions mode, uid and gid
85 hdr.init();
86 char buffer[32];
87 sprintf(buffer, "%-8o", mbr.getMode());
88 memcpy(hdr.mode,buffer,8);
89 sprintf(buffer, "%-6u", mbr.getUser());
90 memcpy(hdr.uid,buffer,6);
91 sprintf(buffer, "%-6u", mbr.getGroup());
92 memcpy(hdr.gid,buffer,6);
93
94 // Set the last modification date
95 uint64_t secondsSinceEpoch = mbr.getModTime().toEpochTime();
96 sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch));
97 memcpy(hdr.date,buffer,12);
98
99 // Get rid of trailing blanks in the name
100 std::string mbrPath = mbr.getPath().str();
101 size_t mbrLen = mbrPath.length();
102 while (mbrLen > 0 && mbrPath[mbrLen-1] == ' ') {
103 mbrPath.erase(mbrLen-1,1);
104 mbrLen--;
105 }
106
107 // Set the name field in one of its various flavors.
108 bool writeLongName = false;
109 if (mbr.isStringTable()) {
110 memcpy(hdr.name,ARFILE_STRTAB_NAME,16);
111 } else if (mbr.isSVR4SymbolTable()) {
112 memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16);
113 } else if (mbr.isBSD4SymbolTable()) {
114 memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16);
115 } else if (TruncateNames) {
116 const char* nm = mbrPath.c_str();
117 unsigned len = mbrPath.length();
118 size_t slashpos = mbrPath.rfind('/');
119 if (slashpos != std::string::npos) {
120 nm += slashpos + 1;
121 len -= slashpos +1;
122 }
123 if (len > 15)
124 len = 15;
125 memcpy(hdr.name,nm,len);
126 hdr.name[len] = '/';
127 } else if (mbrPath.length() < 16 && mbrPath.find('/') == std::string::npos) {
128 memcpy(hdr.name,mbrPath.c_str(),mbrPath.length());
129 hdr.name[mbrPath.length()] = '/';
130 } else {
131 std::string nm = "#1/";
132 nm += utostr(mbrPath.length());
133 memcpy(hdr.name,nm.data(),nm.length());
134 if (sz < 0)
135 sz -= mbrPath.length();
136 else
137 sz += mbrPath.length();
138 writeLongName = true;
139 }
140
141 // Set the size field
142 if (sz < 0) {
143 buffer[0] = '-';
144 sprintf(&buffer[1],"%-9u",(unsigned)-sz);
145 } else {
146 sprintf(buffer, "%-10u", (unsigned)sz);
147 }
148 memcpy(hdr.size,buffer,10);
149
150 return writeLongName;
151 }
152
153 // Insert a file into the archive before some other member. This also takes care
154 // of extracting the necessary flags and information from the file.
155 bool
156 Archive::addFileBefore(const sys::Path& filePath, iterator where,
157 std::string* ErrMsg) {
158 bool Exists;
159 if (sys::fs::exists(filePath.str(), Exists) || !Exists) {
160 if (ErrMsg)
161 *ErrMsg = "Can not add a non-existent file to archive";
162 return true;
163 }
164
165 ArchiveMember* mbr = new ArchiveMember(this);
166
167 mbr->data = 0;
168 mbr->path = filePath;
169 const sys::FileStatus *FSInfo = mbr->path.getFileStatus(false, ErrMsg);
170 if (!FSInfo) {
171 delete mbr;
172 return true;
173 }
174 mbr->info = *FSInfo;
175
176 unsigned flags = 0;
177 bool hasSlash = filePath.str().find('/') != std::string::npos;
178 if (hasSlash)
179 flags |= ArchiveMember::HasPathFlag;
180 if (hasSlash || filePath.str().length() > 15)
181 flags |= ArchiveMember::HasLongFilenameFlag;
182
183 sys::fs::file_magic type;
184 if (sys::fs::identify_magic(mbr->path.str(), type))
185 type = sys::fs::file_magic::unknown;
186 switch (type) {
187 case sys::fs::file_magic::bitcode:
188 flags |= ArchiveMember::BitcodeFlag;
189 break;
190 default:
191 break;
192 }
193 mbr->flags = flags;
194 members.insert(where,mbr);
195 return false;
196 }
197
198 // Write one member out to the file.
199 bool
200 Archive::writeMember(
201 const ArchiveMember& member,
202 std::ofstream& ARFile,
203 bool CreateSymbolTable,
204 bool TruncateNames,
205 std::string* ErrMsg
206 ) {
207
208 unsigned filepos = ARFile.tellp();
209 filepos -= 8;
210
211 // Get the data and its size either from the
212 // member's in-memory data or directly from the file.
213 size_t fSize = member.getSize();
214 const char *data = (const char*)member.getData();
215 MemoryBuffer *mFile = 0;
216 if (!data) {
217 OwningPtr File;
218 if (error_code ec = MemoryBuffer::getFile(member.getPath().c_str(), File)) {
219 if (ErrMsg)
220 *ErrMsg = ec.message();
221 return true;
222 }
223 mFile = File.take();
224 data = mFile->getBufferStart();
225 fSize = mFile->getBufferSize();
226 }
227
228 // Now that we have the data in memory, update the
229 // symbol table if it's a bitcode file.
230 if (CreateSymbolTable && member.isBitcode()) {
<