[lld] r195592 - [PECOFF] Infer subsystem from the entry point function.

Rui Ueyama ruiu at google.com
Sun Nov 24 18:00:00 PST 2013


Author: ruiu
Date: Sun Nov 24 20:00:00 2013
New Revision: 195592

URL: http://llvm.org/viewvc/llvm-project?rev=195592&view=rev
Log:
[PECOFF] Infer subsystem from the entry point function.

If /subsystem option is not specified, the linker needs to infer it from the
entry point function. If "main" or "wmain" is defined, it's a console
application. If "WinMain" or "wWinMain" is defined, it's a GUI application.

Added:
    lld/trunk/lib/ReaderWriter/PECOFF/SetSubsystemPass.h
    lld/trunk/test/pecoff/Inputs/subsystem.main.yaml
    lld/trunk/test/pecoff/Inputs/subsystem.winmain.yaml
    lld/trunk/test/pecoff/subsystem.test
Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
    lld/trunk/test/pecoff/baseaddr.test
    lld/trunk/test/pecoff/dosstub.test
    lld/trunk/test/pecoff/options.test
    lld/trunk/test/pecoff/trivial.test

Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=195592&r1=195591&r2=195592&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Sun Nov 24 20:00:00 2013
@@ -11,6 +11,7 @@
 #include "GroupedSectionsPass.h"
 #include "IdataPass.h"
 #include "LinkerGeneratedSymbolFile.h"
+#include "SetSubsystemPass.h"
 
 #include "lld/Core/PassManager.h"
 #include "lld/Passes/LayoutPass.h"
@@ -204,6 +205,7 @@ PECOFFLinkingContext::stringFromRelocKin
 }
 
 void PECOFFLinkingContext::addPasses(PassManager &pm) {
+  pm.add(std::unique_ptr<Pass>(new pecoff::SetSubsystemPass(*this)));
   pm.add(std::unique_ptr<Pass>(new pecoff::GroupedSectionsPass()));
   pm.add(std::unique_ptr<Pass>(new pecoff::IdataPass(*this)));
   pm.add(std::unique_ptr<Pass>(new LayoutPass()));

Added: lld/trunk/lib/ReaderWriter/PECOFF/SetSubsystemPass.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/SetSubsystemPass.h?rev=195592&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/SetSubsystemPass.h (added)
+++ lld/trunk/lib/ReaderWriter/PECOFF/SetSubsystemPass.h Sun Nov 24 20:00:00 2013
@@ -0,0 +1,56 @@
+//===- lib/ReaderWriter/PECOFF/SetSubsystemPass.h -------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_PE_COFF_SET_SUBSYSTEM_PASS_H
+#define LLD_READER_WRITER_PE_COFF_SET_SUBSYSTEM_PASS_H
+
+#include "lld/ReaderWriter/PECOFFLinkingContext.h"
+
+using llvm::COFF::WindowsSubsystem::IMAGE_SUBSYSTEM_UNKNOWN;
+using llvm::COFF::WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_CUI;
+using llvm::COFF::WindowsSubsystem::IMAGE_SUBSYSTEM_WINDOWS_GUI;
+
+namespace lld {
+namespace pecoff {
+
+/// If "main" or "wmain" is defined, /subsystem:console is the default. If
+/// "WinMain" or "wWinMain" is defined, /subsystem:windows is the default.
+class SetSubsystemPass : public lld::Pass {
+public:
+  SetSubsystemPass(PECOFFLinkingContext &ctx) : _ctx(ctx) {}
+
+  virtual void perform(std::unique_ptr<MutableFile> &file) {
+    if (_ctx.getSubsystem() != IMAGE_SUBSYSTEM_UNKNOWN)
+      return;
+    StringRef main = _ctx.decorateSymbol("main");
+    StringRef wmain = _ctx.decorateSymbol("wmain");
+    StringRef winmain = _ctx.decorateSymbol("WinMain");
+    StringRef wwinmain = _ctx.decorateSymbol("wWinMain");
+    for (auto *atom : file->defined()) {
+      StringRef s = atom->name();
+      if (s == main || s == wmain) {
+        _ctx.setSubsystem(IMAGE_SUBSYSTEM_WINDOWS_CUI);
+        return;
+      }
+      if (s == winmain || s == wwinmain) {
+        _ctx.setSubsystem(IMAGE_SUBSYSTEM_WINDOWS_GUI);
+        return;
+      }
+    }
+    llvm_unreachable("Failed to infer the subsystem.");
+  }
+
+private:
+  PECOFFLinkingContext &_ctx;
+};
+
+} // namespace pecoff
+} // namespace lld
+
+#endif

Added: lld/trunk/test/pecoff/Inputs/subsystem.main.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/subsystem.main.yaml?rev=195592&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/subsystem.main.yaml (added)
+++ lld/trunk/test/pecoff/Inputs/subsystem.main.yaml Sun Nov 24 20:00:00 2013
@@ -0,0 +1,25 @@
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     B82A000000C3
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    NumberOfAuxSymbols: 1
+    AuxiliaryData:   060000000000000000000000000000000000
+  - Name:            _main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

Added: lld/trunk/test/pecoff/Inputs/subsystem.winmain.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/subsystem.winmain.yaml?rev=195592&view=auto
==============================================================================
--- lld/trunk/test/pecoff/Inputs/subsystem.winmain.yaml (added)
+++ lld/trunk/test/pecoff/Inputs/subsystem.winmain.yaml Sun Nov 24 20:00:00 2013
@@ -0,0 +1,25 @@
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     B82A000000C3
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    NumberOfAuxSymbols: 1
+    AuxiliaryData:   060000000000000000000000000000000000
+  - Name:            _WinMain
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

Modified: lld/trunk/test/pecoff/baseaddr.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/baseaddr.test?rev=195592&r1=195591&r2=195592&view=diff
==============================================================================
--- lld/trunk/test/pecoff/baseaddr.test (original)
+++ lld/trunk/test/pecoff/baseaddr.test Sun Nov 24 20:00:00 2013
@@ -1,9 +1,11 @@
 # RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
 #
-# RUN: lld -flavor link /out:%t1 /opt:noref -- %t.obj \
+# RUN: lld -flavor link /out:%t1 /opt:noref /subsystem:console /force \
+# RUN:   -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t1 | FileCheck -check-prefix=DEFAULT %s
 #
-# RUN: lld -flavor link /out:%t1 /opt:noref /base:8388608 -- %t.obj \
+# RUN: lld -flavor link /out:%t1 /opt:noref /base:8388608 /subsystem:console \
+# RUN:   /force -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t1 | FileCheck -check-prefix=BASE %s
 
 DEFAULT: ImageBase: 0x400000
@@ -11,7 +13,7 @@ DEFAULT: ImageBase: 0x400000
 BASE: ImageBase: 0x800000
 
 
-# RUN: not lld -flavor link /base:3 -- %t.obj >& %t.log
+# RUN: not lld -flavor link /base:3 /subsystem:console -- %t.obj >& %t.log
 # RUN: FileCheck -check-prefix=ERROR %s < %t.log
 
 ERROR: Base address have to be multiple of 64K, but got 3

Modified: lld/trunk/test/pecoff/dosstub.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/dosstub.test?rev=195592&r1=195591&r2=195592&view=diff
==============================================================================
--- lld/trunk/test/pecoff/dosstub.test (original)
+++ lld/trunk/test/pecoff/dosstub.test Sun Nov 24 20:00:00 2013
@@ -1,7 +1,8 @@
 # RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
 
 # RUN: echo "MZ Hello world" > %t.stub
-# RUN: lld -flavor link /out:%t.exe /entry:start /stub:%t.stub -- %t.obj
+# RUN: lld -flavor link /out:%t.exe /entry:start /subsystem:console \
+# RUN:   /stub:%t.stub -- %t.obj
 # RUN: FileCheck -check-prefix=FILE %s < %t.exe
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=READOBJ %s
 

Modified: lld/trunk/test/pecoff/options.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/options.test?rev=195592&r1=195591&r2=195592&view=diff
==============================================================================
--- lld/trunk/test/pecoff/options.test (original)
+++ lld/trunk/test/pecoff/options.test Sun Nov 24 20:00:00 2013
@@ -2,26 +2,31 @@
 #
 # RUN: yaml2obj %p/Inputs/nop.obj.yaml > %t.obj
 
-# RUN: lld -flavor link /align:8192 /out:%t.exe /entry:start -- %t.obj \
+# RUN: lld -flavor link /align:8192 /out:%t.exe /entry:start \
+# RUN:   /subsystem:console -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ALIGN %s
 ALIGN: SectionAlignment: 8192
 
-# RUN: lld -flavor link /allowbind:no /out:%t.exe /entry:start -- %t.obj \
+# RUN: lld -flavor link /allowbind:no /out:%t.exe /entry:start \
+# RUN:   /subsystem:console -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t.exe \
 # RUN:   | FileCheck -check-prefix=NOBIND %s
 NOBIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND
 
-# RUN: lld -flavor link /allowisolation:no /out:%t.exe /entry:start -- %t.obj \
+# RUN: lld -flavor link /allowisolation:no /out:%t.exe /entry:start \
+# RUN:   /subsystem:console -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t.exe \
 # RUN:   | FileCheck -check-prefix=NOISOLATION %s
 NOISOLATION: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
 
-# RUN: lld -flavor link /swaprun:cd /out:%t.exe /entry:start -- %t.obj \
+# RUN: lld -flavor link /swaprun:cd /out:%t.exe /entry:start \
+# RUN:   /subsystem:console -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t.exe \
 # RUN:   | FileCheck -check-prefix=SWAPRUNCD %s
 SWAPRUNCD: IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
 
-# RUN: lld -flavor link /swaprun:net /out:%t.exe /entry:start -- %t.obj \
+# RUN: lld -flavor link /swaprun:net /out:%t.exe /entry:start \
+# RUN:   /subsystem:console -- %t.obj \
 # RUN:   && llvm-readobj -file-headers %t.exe \
 # RUN:   | FileCheck -check-prefix=SWAPRUNNET %s
 SWAPRUNNET: IMAGE_FILE_NET_RUN_FROM_SWAP

Added: lld/trunk/test/pecoff/subsystem.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/subsystem.test?rev=195592&view=auto
==============================================================================
--- lld/trunk/test/pecoff/subsystem.test (added)
+++ lld/trunk/test/pecoff/subsystem.test Sun Nov 24 20:00:00 2013
@@ -0,0 +1,12 @@
+# RUN: yaml2obj %p/Inputs/subsystem.main.yaml  > %t.main.obj
+# RUN: yaml2obj %p/Inputs/subsystem.winmain.yaml > %t.winmain.obj
+#
+# RUN: lld -flavor link /out:%t.main.exe -- %t.main.obj
+# RUN: llvm-readobj -file-headers %t.main.exe | FileCheck -check-prefix=MAIN %s
+#
+# RUN: lld -flavor link /out:%t.winmain.exe -- %t.winmain.obj
+# RUN: llvm-readobj -file-headers %t.winmain.exe | \
+# RUN:   FileCheck -check-prefix=WINMAIN %s
+
+MAIN:    Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
+WINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI

Modified: lld/trunk/test/pecoff/trivial.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/trivial.test?rev=195592&r1=195591&r2=195592&view=diff
==============================================================================
--- lld/trunk/test/pecoff/trivial.test (original)
+++ lld/trunk/test/pecoff/trivial.test Sun Nov 24 20:00:00 2013
@@ -8,7 +8,8 @@
 # RUN:   /entry:start /opt:noref -- %t.obj && llvm-readobj -file-headers %t1 \
 # RUN:   | FileCheck -check-prefix=FILE %s
 #
-# RUN: lld -flavor link /out:%t1 /entry:start /opt:noref -- %t.obj \
+# RUN: lld -flavor link /out:%t1 /subsystem:console /entry:start /opt:noref \
+# RUN:   -- %t.obj \
 # RUN:   && llvm-readobj -sections %t1 | FileCheck -check-prefix=SECTIONS %s
 
 FILE: Format: COFF-i386





More information about the llvm-commits mailing list