]>
Commit | Line | Data |
---|---|---|
ebf6f434 A |
1 | // |
2 | // Snapshot.h | |
3 | // ld64 | |
4 | // | |
5 | // Created by Josh Behnke on 8/25/11. | |
6 | // Copyright (c) 2011 Apple Inc. All rights reserved. | |
7 | // | |
8 | ||
9 | #ifndef ld64_Snapshot_h | |
10 | #define ld64_Snapshot_h | |
11 | #include <stdint.h> | |
12 | #include <string.h> | |
13 | #include <map> | |
14 | #include <vector> | |
15 | ||
16 | #include "ld.hpp" | |
17 | ||
18 | class Options; | |
19 | class SnapshotLogItem; | |
20 | ||
21 | class Snapshot { | |
22 | ||
23 | public: | |
24 | static Snapshot *globalSnapshot; | |
25 | ||
26 | typedef enum { | |
27 | SNAPSHOT_DISABLED, // nothing is recorded | |
28 | SNAPSHOT_DEBUG, // records: .o, .dylib, .framework, .a, and other data files | |
29 | } SnapshotMode; | |
30 | ||
31 | Snapshot(); | |
32 | ~Snapshot(); | |
33 | ||
34 | // Control the data captured in the snapshot | |
35 | void setSnapshotMode(SnapshotMode mode); | |
36 | ||
37 | // Use the basename of path to construct the snapshot name. | |
38 | // Must be called prior to createSnapshot(). | |
39 | void setSnapshotName(const char *path); | |
40 | ||
41 | // Set the directory in which the snapshot will be created. | |
42 | // Must be called prior to createSnapshot(). | |
43 | void setSnapshotPath(const char *path); | |
44 | ||
45 | // Stores the linker command line in the snapshot | |
46 | void recordRawArgs(int argc, const char *argv[]); | |
47 | ||
48 | // Adds one or more args to the snapshot link command. | |
49 | // argIndex is the index in the original raw args vector to start adding args | |
50 | // argCount is the count of args to copy from the raw args vector | |
51 | // fileArg is the index relative to argIndex of a file arg. The file is copied into the | |
52 | // snapshot and the path is fixed up in the snapshot link command. (skipped if fileArg==-1) | |
53 | // recordRawArgs() must be called prior to the first call to addSnapshotLinkArg() | |
54 | void addSnapshotLinkArg(int argIndex, int argCount=1, int fileArg=-1); | |
55 | ||
56 | // record the -arch string | |
57 | void recordArch(const char *arch); | |
58 | ||
59 | // Stores an object file in the snapshot, using a unique name in an "objects" subdir. | |
60 | void recordObjectFile(const char *path); | |
61 | ||
62 | // Records symbol names used in dylibs. Does not store anything in the snapshot. | |
63 | void recordDylibSymbol(ld::dylib::File* dylibFile, const char *name); | |
64 | ||
65 | // Stores an archive (.a) file in the snapshot. | |
66 | void recordArchive(const char *archiveFile); | |
67 | ||
68 | // Copies the framework binary into the snapshot frameworks directory. | |
69 | void recordSubUmbrella(const char *frameworkPath); | |
70 | ||
71 | // Copies the library binary into the snapshot dylibs directory. | |
72 | void recordSubLibrary(const char *dylibPath); | |
73 | ||
74 | // Records arbitrary text messages into a log file in the snapshot. | |
75 | // Used by the assertion failure machienery. | |
76 | void recordAssertionMessage(const char *fmt, ...); | |
77 | ||
78 | // Create the snapshot. | |
79 | // Until this is called the snapshot operates lazily, storing minimal data in memory. | |
80 | // When this is called the snapshot is created and any previously recorded data is | |
81 | // immediately copied. Any subsequent additions to the snapshot are copied immediately. | |
82 | void createSnapshot(); | |
83 | ||
84 | // Returns the snapshot root directory. | |
85 | const char *rootDir() { return fRootDir; } | |
86 | ||
87 | private: | |
88 | ||
89 | friend class SnapshotArchiveFileLog; | |
90 | ||
91 | typedef std::vector<void(^)(void)> SnapshotLog; | |
92 | ||
93 | struct strcompclass { | |
94 | bool operator() (const char *a, const char *b) const { return ::strcmp(a, b) < 0; } | |
95 | }; | |
96 | typedef std::vector<const char *> StringVector; | |
97 | typedef std::map<const char *, int, strcompclass > DylibMap; | |
98 | typedef std::map<const char *, const char *, strcompclass> PathMap; | |
99 | ||
100 | ||
101 | // Write the current contents of the args vector to a file in the snapshot. | |
102 | // If filename is NULL then "link_command" is used. | |
103 | // This is used to write both the original and the "cooked" versions of the link command | |
104 | void writeCommandLine(StringVector &args, const char *filename=NULL, bool includeCWD=false); | |
105 | ||
106 | // Construct a path in the snapshot. | |
107 | // buf is a sring buffer in which the path is constructed | |
108 | // subdir is an optional subdirectory, and file is a file name | |
109 | // Constructs the path <snapshot_root>/<subdir>/<file> in buf | |
110 | void buildPath(char *buf, const char *subdir, const char *file); | |
111 | ||
112 | // Similar to buildPath(), except this ensures the returned path | |
113 | // does not reference an existing file in the snapshot. | |
114 | // Performs uniquing by appending a count suffex to the path (ie .../file-XX) | |
115 | void buildUniquePath(char *buf, const char *subdir, const char *file); | |
116 | ||
117 | // Copies an arbitrary file to the snapshot. Subdir specifies an optional subdirectory name. | |
118 | // Uses buildUniquePath to construct a unique path. If the result path is needed by the caller | |
119 | // then a path buffer can be supplied in buf. Otherwise an internal buffer is used. | |
120 | void copyFileToSnapshot(const char *sourcePath, const char *subdir, char *buf=NULL); | |
121 | ||
122 | // Convert a full path to snapshot relative by constructing an interior pointer at the right offset. | |
123 | const char *snapshotRelativePath(const char *path) { return path+strlen(fRootDir)+1; } | |
124 | ||
125 | // returns true if the snapshot has not been created (by createSnapshot()) yet | |
126 | bool isLazy() { return fRootDir == NULL; } | |
127 | ||
128 | void addFrameworkArg(const char *framework); | |
129 | void addDylibArg(const char *dylib); | |
130 | ||
131 | SnapshotLog fLog; // log of events that recorded data in a snapshot prior to createSnapshot() | |
132 | bool fRecordArgs; // record command line | |
133 | bool fRecordObjects; // record .o files | |
134 | bool fRecordDylibSymbols; // record referenced dylib/framework symbols | |
135 | bool fRecordArchiveFiles; // record .a files | |
136 | bool fRecordUmbrellaFiles; // record re-exported sub frameworks/dylibs | |
137 | bool fRecordDataFiles; // record other data files | |
138 | bool fFrameworkArgAdded; | |
139 | ||
140 | const char *fSnapshotLocation; // parent directory of frootDir | |
141 | const char *fSnapshotName; // a string to use in constructing the snapshot name | |
142 | char *fRootDir; // root directory of the snapshot | |
143 | int fFilelistFile; // file descriptor to the open text file used for the -filelist | |
144 | ||
145 | StringVector fRawArgs; // stores the raw command line args | |
146 | StringVector fArgs; // stores the "cooked" command line args | |
147 | PathMap fPathMap; // mapping of original paths->snapshot paths for copied files | |
148 | ||
149 | DylibMap fDylibSymbols; // map of dylib names to string vector containing referenced symbol names | |
150 | StringVector *fCopiedArchives; // vector of .a files that have been copied to the snapshot | |
151 | }; | |
152 | ||
153 | #endif |