@@ -42,24 +42,28 @@ void anchorForGetMainExecutable() {}
42
42
43
43
using namespace llvm ::MachO;
44
44
45
- static void printValidationInfo (llvm::StringRef data) {
45
+ static bool validateModule (llvm::StringRef data, bool Verbose ) {
46
46
swift::serialization::ExtendedValidationInfo extendedInfo;
47
47
swift::serialization::ValidationInfo info =
48
48
swift::serialization::validateSerializedAST (data, &extendedInfo);
49
49
if (info.status != swift::serialization::Status::Valid)
50
- return ;
51
-
52
- if (!info.shortVersion .empty ())
53
- llvm::outs () << " - Swift Version: " << info.shortVersion << " \n " ;
54
- llvm::outs () << " - Target: " << info.targetTriple << " \n " ;
55
- if (!extendedInfo.getSDKPath ().empty ())
56
- llvm::outs () << " - SDK path: " << extendedInfo.getSDKPath () << " \n " ;
57
- if (!extendedInfo.getExtraClangImporterOptions ().empty ()) {
58
- llvm::outs () << " - -Xcc options:" ;
59
- for (llvm::StringRef option : extendedInfo.getExtraClangImporterOptions ())
60
- llvm::outs () << " " << option;
61
- llvm::outs () << " \n " ;
50
+ return false ;
51
+
52
+ if (Verbose) {
53
+ if (!info.shortVersion .empty ())
54
+ llvm::outs () << " - Swift Version: " << info.shortVersion << " \n " ;
55
+ llvm::outs () << " - Target: " << info.targetTriple << " \n " ;
56
+ if (!extendedInfo.getSDKPath ().empty ())
57
+ llvm::outs () << " - SDK path: " << extendedInfo.getSDKPath () << " \n " ;
58
+ if (!extendedInfo.getExtraClangImporterOptions ().empty ()) {
59
+ llvm::outs () << " - -Xcc options:" ;
60
+ for (llvm::StringRef option : extendedInfo.getExtraClangImporterOptions ())
61
+ llvm::outs () << " " << option;
62
+ llvm::outs () << " \n " ;
63
+ }
62
64
}
65
+
66
+ return true ;
63
67
}
64
68
65
69
static void resolveDeclFromMangledNameList (
@@ -104,6 +108,64 @@ collectMangledNames(const std::string &FilePath,
104
108
}
105
109
}
106
110
111
+ llvm::BumpPtrAllocator Alloc;
112
+
113
+ static bool
114
+ collectASTModules (llvm::cl::list<std::string> &InputNames,
115
+ llvm::SmallVectorImpl<std::pair<char *, uint64_t >> &Modules) {
116
+ for (auto &name : InputNames) {
117
+ auto OF = llvm::object::ObjectFile::createObjectFile (name);
118
+ if (!OF) {
119
+ llvm::outs () << name << " is not an object file.\n " ;
120
+ return false ;
121
+ }
122
+ auto *Obj = OF->getBinary ();
123
+ auto *MachO = llvm::dyn_cast<llvm::object::MachOObjectFile>(Obj);
124
+ auto *ELF = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Obj);
125
+
126
+ if (MachO) {
127
+ for (auto &Symbol : Obj->symbols ()) {
128
+ auto RawSym = Symbol.getRawDataRefImpl ();
129
+ llvm::MachO::nlist nlist = MachO->getSymbolTableEntry (RawSym);
130
+ if (nlist.n_type != N_AST)
131
+ continue ;
132
+ auto Path = MachO->getSymbolName (RawSym);
133
+ if (!Path) {
134
+ llvm::outs () << " Cannot get symbol name\n ;" ;
135
+ return false ;
136
+ }
137
+
138
+ auto fileBuf = llvm::MemoryBuffer::getFile (*Path);
139
+ if (!fileBuf) {
140
+ llvm::outs () << " Cannot read from '" << *Path
141
+ << " ': " << fileBuf.getError ().message ();
142
+ return false ;
143
+ }
144
+
145
+ uint64_t Size = fileBuf.get ()->getBufferSize ();
146
+ char *Module = Alloc.Allocate <char >(Size);
147
+ std::memcpy (Module, (void *)fileBuf.get ()->getBufferStart (), Size);
148
+ Modules.push_back ({Module, Size});
149
+ }
150
+ }
151
+
152
+ for (auto &Section : Obj->sections ()) {
153
+ llvm::StringRef Name;
154
+ Section.getName (Name);
155
+ if ((MachO && Name == swift::MachOASTSectionName) ||
156
+ (ELF && Name == swift::ELFASTSectionName)) {
157
+ uint64_t Size = Section.getSize ();
158
+ StringRef ContentsReference;
159
+ Section.getContents (ContentsReference);
160
+ char *Module = Alloc.Allocate <char >(Size);
161
+ std::memcpy (Module, (void *)ContentsReference.begin (), Size);
162
+ Modules.push_back ({Module, Size});
163
+ }
164
+ }
165
+ }
166
+ return true ;
167
+ }
168
+
107
169
int main (int argc, char **argv) {
108
170
PROGRAM_START (argc, argv);
109
171
INITIALIZE_LLVM ();
@@ -154,6 +216,19 @@ int main(int argc, char **argv) {
154
216
InputNames.removeArgument ();
155
217
TargetTriple.removeArgument ();
156
218
219
+ // Fetch the serialized module bitstreams from the Mach-O files and
220
+ // register them with the module loader.
221
+ llvm::SmallVector<std::pair<char *, uint64_t >, 8 > Modules;
222
+ if (!collectASTModules (InputNames, Modules))
223
+ return 1 ;
224
+
225
+ for (auto &Module : Modules) {
226
+ if (!validateModule (StringRef (Module.first , Module.second ), Verbose)) {
227
+ llvm::errs () << " Malformed module!\n " ;
228
+ return 1 ;
229
+ }
230
+ }
231
+
157
232
// If no SDK was specified via -sdk, check environment variable SDKROOT.
158
233
if (SDK.getNumOccurrences () == 0 ) {
159
234
const char *SDKROOT = getenv (" SDKROOT" );
@@ -190,75 +265,10 @@ int main(int argc, char **argv) {
190
265
if (CI.setup (Invocation))
191
266
return 1 ;
192
267
193
- std::vector<llvm::object::OwningBinary<llvm::object::ObjectFile>> ObjFiles;
194
-
195
- // Fetch the serialized module bitstreams from the Mach-O files and
196
- // register them with the module loader.
197
- for (std::string name : InputNames) {
198
- auto OF = llvm::object::ObjectFile::createObjectFile (name);
199
- if (!OF) {
200
- llvm::outs () << name << " is not an object file.\n " ;
201
- exit (1 );
202
- }
203
- auto *Obj = OF->getBinary ();
204
- auto *MachO = llvm::dyn_cast<llvm::object::MachOObjectFile>(Obj);
205
- auto *ELF = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Obj);
206
- if (MachO) {
207
- for (auto &Symbol : Obj->symbols ()) {
208
- auto RawSym = Symbol.getRawDataRefImpl ();
209
- llvm::MachO::nlist nlist = MachO->getSymbolTableEntry (RawSym);
210
- if (nlist.n_type == N_AST) {
211
- auto Path = MachO->getSymbolName (RawSym);
212
- if (!Path) {
213
- llvm::outs () << " Cannot get symbol name\n ;" ;
214
- exit (1 );
215
- }
216
-
217
- auto fileBuf = llvm::MemoryBuffer::getFile (*Path);
218
- if (!fileBuf) {
219
- llvm::outs () << " Cannot read from '" << *Path
220
- << " ': " << fileBuf.getError ().message ();
221
- exit (1 );
222
- }
223
-
224
- if (!parseASTSection (CI.getSerializedModuleLoader (),
225
- fileBuf.get ()->getBuffer (), modules)) {
226
- exit (1 );
227
- }
228
-
229
- if (Verbose) {
230
- for (auto path : modules)
231
- llvm::outs () << " Loaded module " << path << " from " << name
232
- << " \n " ;
233
- printValidationInfo (fileBuf.get ()->getBuffer ());
234
- }
235
-
236
- // Deliberately leak the llvm::MemoryBuffer. We can't delete it
237
- // while it's in use anyway.
238
- fileBuf.get ().release ();
239
- }
240
- }
241
- }
242
- for (auto &Section : Obj->sections ()) {
243
- llvm::StringRef Name;
244
- Section.getName (Name);
245
- if ((MachO && Name == swift::MachOASTSectionName) ||
246
- (ELF && Name == swift::ELFASTSectionName)) {
247
- llvm::StringRef Buf;
248
- Section.getContents (Buf);
249
- if (!parseASTSection (CI.getSerializedModuleLoader (), Buf, modules))
250
- exit (1 );
251
-
252
- if (Verbose) {
253
- for (auto path : modules)
254
- llvm::outs () << " Loaded module " << path << " from " << name
255
- << " \n " ;
256
- printValidationInfo (Buf);
257
- }
258
- }
259
- }
260
- ObjFiles.push_back (std::move (*OF));
261
- }
268
+ for (auto &Module : Modules)
269
+ if (!parseASTSection (CI.getSerializedModuleLoader (),
270
+ StringRef (Module.first , Module.second ), modules))
271
+ return 1 ;
262
272
263
273
// Attempt to import all modules we found.
264
274
for (auto path : modules) {
0 commit comments