forked from OSchip/llvm-project
[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. llvm-svn: 195592
This commit is contained in:
parent
fbd2b4484c
commit
1a11b3b001
|
@ -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::stringFromRelocKind(Reference::Kind kind) const {
|
|||
}
|
||||
|
||||
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()));
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
...
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue