Index: COFF/Driver.h =================================================================== --- COFF/Driver.h +++ COFF/Driver.h @@ -103,6 +103,7 @@ // entry point name. StringRef findDefaultEntry(); WindowsSubsystem inferSubsystem(); + MachineTypes inferMachineType(); // Driver is the owner of all opened files. // InputFiles have MemoryBufferRefs to them. Index: COFF/Driver.cpp =================================================================== --- COFF/Driver.cpp +++ COFF/Driver.cpp @@ -30,9 +30,7 @@ #include using namespace llvm; -using llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN; -using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI; -using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI; +using namespace llvm::COFF; using llvm::sys::Process; using llvm::sys::fs::OpenFlags; using llvm::sys::fs::file_magic; @@ -236,6 +234,16 @@ return IMAGE_SUBSYSTEM_UNKNOWN; } +MachineTypes LinkerDriver::inferMachineType() { + for (ObjectFile *F : Symtab.ObjectFiles) { + // Try to infer machine type from the magic byte of the object file. + auto MT = static_cast(F->getCOFFObj()->getMachine()); + if (MT != IMAGE_FILE_MACHINE_UNKNOWN) + return MT; + } + return IMAGE_FILE_MACHINE_UNKNOWN; +} + bool LinkerDriver::link(llvm::ArrayRef ArgsArr) { // Needed for LTO. llvm::InitializeAllTargetInfos(); @@ -625,6 +633,15 @@ } } + // Windows specific -- if no /machine is givne, infer that. + if (Config->MachineType == IMAGE_FILE_MACHINE_UNKNOWN) { + Config->MachineType = inferMachineType(); + if (Config->MachineType == IMAGE_FILE_MACHINE_UNKNOWN) { + llvm::errs() << "/machine must be specified\n"; + return false; + } + } + // Windows specific -- when we are creating a .dll file, we also // need to create a .lib file. if (!Config->Exports.empty()) Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -298,17 +298,6 @@ RoundUpToAlignment(FileOff - SizeOfHeaders, FileAlignment); } -static MachineTypes -inferMachineType(const std::vector &Files) { - for (ObjectFile *F : Files) { - // Try to infer machine type from the magic byte of the object file. - auto MT = static_cast(F->getCOFFObj()->getMachine()); - if (MT != IMAGE_FILE_MACHINE_UNKNOWN) - return MT; - } - return IMAGE_FILE_MACHINE_UNKNOWN; -} - void Writer::writeHeader() { // Write DOS stub uint8_t *Buf = Buffer->getBufferStart(); @@ -323,15 +312,10 @@ memcpy(Buf, PEMagic, sizeof(PEMagic)); Buf += sizeof(PEMagic); - // Determine machine type, infer if needed. TODO: diagnose conflicts. - MachineTypes MachineType = Config->MachineType; - if (MachineType == IMAGE_FILE_MACHINE_UNKNOWN) - MachineType = inferMachineType(Symtab->ObjectFiles); - // Write COFF header auto *COFF = reinterpret_cast(Buf); Buf += sizeof(*COFF); - COFF->Machine = MachineType; + COFF->Machine = Config->MachineType; COFF->NumberOfSections = OutputSections.size(); COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;