Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -87,24 +87,6 @@ return Filename; } -// Peeks at the file header to get architecture (e.g. i386 or AMD64). -// Returns "unknown" if it's not a valid object file. -static MachineTypes getFileMachineType(StringRef Path) { - file_magic Magic; - if (identify_magic(Path, Magic)) - return IMAGE_FILE_MACHINE_UNKNOWN; - if (Magic != file_magic::coff_object) - return IMAGE_FILE_MACHINE_UNKNOWN; - ErrorOr> BufOrErr = MemoryBuffer::getFile(Path); - if (BufOrErr.getError()) - return IMAGE_FILE_MACHINE_UNKNOWN; - std::error_code EC; - llvm::object::COFFObjectFile Obj(BufOrErr.get()->getMemBufferRef(), EC); - if (EC) - return IMAGE_FILE_MACHINE_UNKNOWN; - return static_cast(Obj.getMachine()); -} - // Returns /machine's value. ErrorOr getMachineType(llvm::opt::InputArgList *Args) { if (auto *Arg = Args->getLastArg(OPT_machine)) { @@ -118,13 +100,6 @@ return make_dynamic_error_code("unknown /machine argument" + S); return MT; } - // If /machine option is missing, we need to take a look at - // the magic byte of the first object file to infer machine type. - for (auto *Arg : Args->filtered(OPT_INPUT)) { - MachineTypes MT = getFileMachineType(Arg->getValue()); - if (MT != IMAGE_FILE_MACHINE_UNKNOWN) - return MT; - } return IMAGE_FILE_MACHINE_UNKNOWN; } Index: COFF/SymbolTable.h =================================================================== --- COFF/SymbolTable.h +++ COFF/SymbolTable.h @@ -49,6 +49,10 @@ // Dump contents of the symbol table to stderr. void dump(); + // Try to infer the machine type from the object files known to the symbol + // table. + llvm::COFF::MachineTypes getInferredMachineType(); + // The writer needs to handle DLL import libraries specially in // order to create the import descriptor table. std::vector> ImportFiles; Index: COFF/SymbolTable.cpp =================================================================== --- COFF/SymbolTable.cpp +++ COFF/SymbolTable.cpp @@ -171,5 +171,16 @@ } } +llvm::COFF::MachineTypes SymbolTable::getInferredMachineType() { + for (std::unique_ptr &File : ObjectFiles) { + // Try to infer machine type from the magic byte of the object file. + auto MT = + static_cast(File->getCOFFObj()->getMachine()); + if (MT != llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN) + return MT; + } + return llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN; +} + } // namespace coff } // namespace lld Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -241,10 +241,14 @@ memcpy(Buf, PEMagic, sizeof(PEMagic)); Buf += sizeof(PEMagic); + MachineTypes MachineType = Config->MachineType; + if (MachineType == IMAGE_FILE_MACHINE_UNKNOWN) + MachineType = Symtab->getInferredMachineType(); + // Write COFF header auto *COFF = reinterpret_cast(Buf); Buf += sizeof(*COFF); - COFF->Machine = Config->MachineType; + COFF->Machine = MachineType; COFF->NumberOfSections = OutputSections.size(); COFF->Characteristics = (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED | Index: test/COFF/machine.test =================================================================== --- test/COFF/machine.test +++ test/COFF/machine.test @@ -1,6 +1,15 @@ # RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \ # RUN: %p/Inputs/ret42.obj # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s +# RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \ +# RUN: %p/Inputs/ret42.lib +# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s +# RUN: lld -flavor link2 /entry:main /out:%t.exe \ +# RUN: %p/Inputs/ret42.obj +# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s +# RUN: lld -flavor link2 /entry:main /out:%t.exe \ +# RUN: %p/Inputs/ret42.lib +# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s AMD64: Machine: IMAGE_FILE_MACHINE_AMD64