@@ -189,6 +189,71 @@ bool LinkerDriver::findUnderscoreMangle(StringRef sym) {
189189 return s && !isa<Undefined>(s);
190190}
191191
192+ static bool compatibleMachineType (COFFLinkerContext &ctx, MachineTypes mt) {
193+ if (mt == IMAGE_FILE_MACHINE_UNKNOWN)
194+ return true ;
195+ switch (ctx.config .machine ) {
196+ case ARM64:
197+ return mt == ARM64 || mt == ARM64X;
198+ case ARM64EC:
199+ return isArm64EC (mt) || mt == AMD64;
200+ case ARM64X:
201+ return isAnyArm64 (mt) || mt == AMD64;
202+ case IMAGE_FILE_MACHINE_UNKNOWN:
203+ return true ;
204+ default :
205+ return ctx.config .machine == mt;
206+ }
207+ }
208+
209+ void LinkerDriver::addFile (InputFile *file) {
210+ Log (ctx) << " Reading " << toString (file);
211+ if (file->lazy ) {
212+ if (auto *f = dyn_cast<BitcodeFile>(file))
213+ f->parseLazy ();
214+ else
215+ cast<ObjFile>(file)->parseLazy ();
216+ } else {
217+ file->parse ();
218+ if (auto *f = dyn_cast<ObjFile>(file)) {
219+ ctx.objFileInstances .push_back (f);
220+ } else if (auto *f = dyn_cast<BitcodeFile>(file)) {
221+ if (ltoCompilationDone) {
222+ Err (ctx) << " LTO object file " << toString (file)
223+ << " linked in after "
224+ " doing LTO compilation." ;
225+ }
226+ ctx.bitcodeFileInstances .push_back (f);
227+ } else if (auto *f = dyn_cast<ImportFile>(file)) {
228+ ctx.importFileInstances .push_back (f);
229+ }
230+ }
231+
232+ MachineTypes mt = file->getMachineType ();
233+ // The ARM64EC target must be explicitly specified and cannot be inferred.
234+ if (mt == ARM64EC &&
235+ (ctx.config .machine == IMAGE_FILE_MACHINE_UNKNOWN ||
236+ (ctx.config .machineInferred &&
237+ (ctx.config .machine == ARM64 || ctx.config .machine == AMD64)))) {
238+ Err (ctx) << toString (file)
239+ << " : machine type arm64ec is ambiguous and cannot be "
240+ " inferred, use /machine:arm64ec or /machine:arm64x" ;
241+ return ;
242+ }
243+ if (!compatibleMachineType (ctx, mt)) {
244+ Err (ctx) << toString (file) << " : machine type " << machineToStr (mt)
245+ << " conflicts with " << machineToStr (ctx.config .machine );
246+ return ;
247+ }
248+ if (ctx.config .machine == IMAGE_FILE_MACHINE_UNKNOWN &&
249+ mt != IMAGE_FILE_MACHINE_UNKNOWN) {
250+ ctx.config .machineInferred = true ;
251+ setMachine (mt);
252+ }
253+
254+ parseDirectives (file);
255+ }
256+
192257MemoryBufferRef LinkerDriver::takeBuffer (std::unique_ptr<MemoryBuffer> mb) {
193258 MemoryBufferRef mbref = *mb;
194259 make<std::unique_ptr<MemoryBuffer>>(std::move (mb)); // take ownership
@@ -222,25 +287,25 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
222287 addArchiveBuffer (m, " <whole-archive>" , filename, memberIndex++);
223288 return ;
224289 }
225- ctx. symtab . addFile (make<ArchiveFile>(ctx, mbref));
290+ addFile (make<ArchiveFile>(ctx, mbref));
226291 break ;
227292 case file_magic::bitcode:
228- ctx. symtab . addFile (make<BitcodeFile>(ctx, mbref, " " , 0 , lazy));
293+ addFile (make<BitcodeFile>(ctx, mbref, " " , 0 , lazy));
229294 break ;
230295 case file_magic::coff_object:
231296 case file_magic::coff_import_library:
232- ctx. symtab . addFile (ObjFile::create (ctx, mbref, lazy));
297+ addFile (ObjFile::create (ctx, mbref, lazy));
233298 break ;
234299 case file_magic::pdb:
235- ctx. symtab . addFile (make<PDBInputFile>(ctx, mbref));
300+ addFile (make<PDBInputFile>(ctx, mbref));
236301 break ;
237302 case file_magic::coff_cl_gl_object:
238303 Err (ctx) << filename
239304 << " : is not a native COFF file. Recompile without /GL" ;
240305 break ;
241306 case file_magic::pecoff_executable:
242307 if (ctx.config .mingw ) {
243- ctx. symtab . addFile (make<DLLFile>(ctx.symtab , mbref));
308+ addFile (make<DLLFile>(ctx.symtab , mbref));
244309 break ;
245310 }
246311 if (filename.ends_with_insensitive (" .dll" )) {
@@ -306,7 +371,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
306371 if (magic == file_magic::coff_import_library) {
307372 InputFile *imp = make<ImportFile>(ctx, mb);
308373 imp->parentName = parentName;
309- ctx. symtab . addFile (imp);
374+ addFile (imp);
310375 return ;
311376 }
312377
@@ -326,7 +391,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
326391 }
327392
328393 obj->parentName = parentName;
329- ctx. symtab . addFile (obj);
394+ addFile (obj);
330395 Log (ctx) << " Loaded " << obj << " for " << symName;
331396}
332397
@@ -1400,7 +1465,7 @@ void LinkerDriver::convertResources() {
14001465 }
14011466 ObjFile *f =
14021467 ObjFile::create (ctx, convertResToCOFF (resources, resourceObjFiles));
1403- ctx. symtab . addFile (f);
1468+ addFile (f);
14041469 f->includeResourceChunks ();
14051470}
14061471
@@ -2702,6 +2767,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
27022767 // Do LTO by compiling bitcode input files to a set of native COFF files then
27032768 // link those files (unless -thinlto-index-only was given, in which case we
27042769 // resolve symbols and write indices, but don't generate native code or link).
2770+ ltoCompilationDone = true ;
27052771 ctx.symtab .compileBitcodeFiles ();
27062772
27072773 if (Defined *d =
0 commit comments