[lld] r241647 - COFF: Check for incompatible machine types.

Rui Ueyama ruiu at google.com
Tue Jul 7 16:39:18 PDT 2015


Author: ruiu
Date: Tue Jul  7 18:39:18 2015
New Revision: 241647

URL: http://llvm.org/viewvc/llvm-project?rev=241647&view=rev
Log:
COFF: Check for incompatible machine types.

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/InputFiles.cpp
    lld/trunk/test/COFF/machine.test

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=241647&r1=241646&r2=241647&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Tue Jul  7 18:39:18 2015
@@ -30,9 +30,7 @@
 #include <memory>
 
 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;
@@ -625,6 +623,28 @@ bool LinkerDriver::link(llvm::ArrayRef<c
     }
   }
 
+  // Check if all object files are for the same CPU type and
+  // compatible with /machine option (if given).
+  for (ObjectFile *File : Symtab.ObjectFiles) {
+    auto MT = static_cast<MachineTypes>(File->getCOFFObj()->getMachine());
+    if (MT == IMAGE_FILE_MACHINE_UNKNOWN)
+      continue;
+    if (Config->MachineType == IMAGE_FILE_MACHINE_UNKNOWN) {
+      Config->MachineType = MT;
+      continue;
+    }
+    if (Config->MachineType != MT) {
+      llvm::errs() << File->getShortName() << ": machine type "
+                   << machineTypeToStr(MT) << " conflicts with "
+                   << machineTypeToStr(Config->MachineType) << "\n";
+      return false;
+    }
+  }
+  if (Config->MachineType == IMAGE_FILE_MACHINE_UNKNOWN) {
+    llvm::errs() << "machine type 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())

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=241647&r1=241646&r2=241647&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Tue Jul  7 18:39:18 2015
@@ -118,6 +118,7 @@ void printHelp(const char *Argv0);
 
 // For /machine option.
 ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args);
+StringRef machineTypeToStr(MachineTypes MT);
 
 // Parses a string in the form of "<integer>[,<integer>]".
 std::error_code parseNumbers(StringRef Arg, uint64_t *Addr,

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=241647&r1=241646&r2=241647&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Tue Jul  7 18:39:18 2015
@@ -96,6 +96,19 @@ ErrorOr<MachineTypes> getMachineType(llv
   return IMAGE_FILE_MACHINE_UNKNOWN;
 }
 
+StringRef machineTypeToStr(MachineTypes MT) {
+  switch (MT) {
+  case IMAGE_FILE_MACHINE_ARMNT:
+    return "arm";
+  case IMAGE_FILE_MACHINE_AMD64:
+    return "x64";
+  case IMAGE_FILE_MACHINE_I386:
+    return "x86";
+  default:
+    llvm_unreachable("unknown machine type");
+  }
+}
+
 // Parses a string in the form of "<integer>[,<integer>]".
 std::error_code parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) {
   StringRef S1, S2;

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=241647&r1=241646&r2=241647&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Tue Jul  7 18:39:18 2015
@@ -111,11 +111,6 @@ std::error_code ObjectFile::parse() {
     llvm::errs() << getName() << " is not a COFF file.\n";
     return make_error_code(LLDError::InvalidFile);
   }
-  if (COFFObj->getMachine() != IMAGE_FILE_MACHINE_AMD64 &&
-      COFFObj->getMachine() != IMAGE_FILE_MACHINE_UNKNOWN) {
-    llvm::errs() << getName() << " is not an x64 object file.\n";
-    return make_error_code(LLDError::InvalidFile);
-  }
 
   // Read section and symbol tables.
   if (auto EC = initializeChunks())

Modified: lld/trunk/test/COFF/machine.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/machine.test?rev=241647&r1=241646&r2=241647&view=diff
==============================================================================
--- lld/trunk/test/COFF/machine.test (original)
+++ lld/trunk/test/COFF/machine.test Tue Jul  7 18:39:18 2015
@@ -1,20 +1,61 @@
-# RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x64 \
-# RUN:   /out:%t.exe %p/Inputs/ret42.obj
+# RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_AMD64/ %s | yaml2obj > %t.obj
+# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
 # RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x64 \
-# RUN:   /out:%t.exe %p/Inputs/ret42.lib
-# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
-# RUN: lld -flavor link2 /entry:main /subsystem:console /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 /subsystem:console /out:%t.exe \
-# RUN:   %p/Inputs/ret42.lib
+# RUN:   /out:%t.exe %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
 
-AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
+# AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
 
+# RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_I386/ %s | yaml2obj > %t.obj
+# RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
 # RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x86 \
-# RUN:   /out:%t.exe %p/Inputs/ret42.obj
+# RUN:   /out:%t.exe %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
 
-I386: Machine: IMAGE_FILE_MACHINE_I386
+# I386: Machine: IMAGE_FILE_MACHINE_I386
+
+# RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_AMD64/ %s | yaml2obj > %t.obj
+# RUN: not lld -flavor link2 /entry:main /subsystem:console /machine:x86 \
+# RUN:   /out:%t.exe %t.obj >& %t.log
+# RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log
+
+# RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_I386/ %s | yaml2obj > %t1.obj
+# RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_AMD64/ %s | \
+# RUN:   sed -e s/main/foo/ | yaml2obj > %t2.obj
+# RUN: not lld -flavor link2 /entry:main /subsystem:console /out:%t.exe \
+# RUN:   %t1.obj %t2.obj >& %t.log
+# RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log
+
+# INCOMPAT: .obj: machine type x64 conflicts with x86
+
+---
+header:
+  Machine:         MACHINETYPE
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     000000000000
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          6
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...





More information about the llvm-commits mailing list