[lld] r182988 - [WinLink][Driver] Add support for -subsystem optional OS version number.
Rui Ueyama
ruiu at google.com
Thu May 30 23:30:10 PDT 2013
Author: ruiu
Date: Fri May 31 01:30:10 2013
New Revision: 182988
URL: http://llvm.org/viewvc/llvm-project?rev=182988&view=rev
Log:
[WinLink][Driver] Add support for -subsystem optional OS version number.
Modified:
lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
lld/trunk/lib/Driver/WinLinkDriver.cpp
lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
Modified: lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h?rev=182988&r1=182987&r2=182988&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h (original)
+++ lld/trunk/include/lld/ReaderWriter/PECOFFTargetInfo.h Fri May 31 01:30:10 2013
@@ -21,7 +21,9 @@ namespace lld {
class PECOFFTargetInfo : public TargetInfo {
public:
- PECOFFTargetInfo() : _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN) {}
+ PECOFFTargetInfo()
+ : _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN),
+ _minOSVersion(6, 0) {}
virtual error_code parseFile(
std::unique_ptr<MemoryBuffer> &mb,
@@ -43,8 +45,23 @@ public:
virtual ErrorOr<Reference::Kind> relocKindFromString(StringRef str) const;
virtual ErrorOr<std::string> stringFromRelocKind(Reference::Kind kind) const;
+ struct OSVersion {
+ OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {}
+ int majorVersion;
+ int minorVersion;
+ };
+
+ void setMinOSVersion(const OSVersion &version) {
+ _minOSVersion = version;
+ }
+
+ OSVersion getMinOSVersion() const {
+ return _minOSVersion;
+ }
+
private:
llvm::COFF::WindowsSubsystem _subsystem;
+ OSVersion _minOSVersion;
mutable std::unique_ptr<Reader> _reader;
mutable std::unique_ptr<Writer> _writer;
Modified: lld/trunk/lib/Driver/WinLinkDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/WinLinkDriver.cpp?rev=182988&r1=182987&r2=182988&view=diff
==============================================================================
--- lld/trunk/lib/Driver/WinLinkDriver.cpp (original)
+++ lld/trunk/lib/Driver/WinLinkDriver.cpp Fri May 31 01:30:10 2013
@@ -13,6 +13,8 @@
///
//===----------------------------------------------------------------------===//
+#include <cstdlib>
+
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/Option.h"
@@ -64,15 +66,66 @@ int findDoubleDash(int argc, const char
return -1;
}
-// Parses -subsystem command line option.
-llvm::COFF::WindowsSubsystem strToWinSubsystem(std::string str) {
- std::string arg(StringRef(str).lower());
+// Returns subsystem type for the given string.
+llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) {
+ std::string arg(str.lower());
return llvm::StringSwitch<llvm::COFF::WindowsSubsystem>(arg)
.Case("windows", llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI)
.Case("console", llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI)
.Default(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN);
}
+
+// Displays error message if the given version does not match with
+// /^\d+$/.
+bool checkOSVersion(StringRef version, const char *errorMessage,
+ raw_ostream &diagnostics) {
+ if (version.str().find_first_not_of("0123456789") != std::string::npos
+ || version.empty()) {
+ diagnostics << "error: " << errorMessage << version << "\n";
+ return false;
+ }
+ return true;
+}
+
+bool parseMinOSVersion(PECOFFTargetInfo &info, StringRef &osVersion,
+ raw_ostream &diagnostics) {
+ StringRef majorVersion, minorVersion;
+ llvm::tie(majorVersion, minorVersion) = osVersion.split('.');
+ if (minorVersion.empty())
+ minorVersion = "0";
+ if (!checkOSVersion(majorVersion, "invalid OS major version: ", diagnostics))
+ return false;
+ if (!checkOSVersion(minorVersion, "invalid OS minor version: ", diagnostics))
+ return false;
+ PECOFFTargetInfo::OSVersion minOSVersion(atoi(majorVersion.str().c_str()),
+ atoi(minorVersion.str().c_str()));
+ info.setMinOSVersion(minOSVersion);
+ return true;
+}
+
+// Parse -subsystem command line option. The form of -subsystem is
+// "subsystem_name[,majorOSVersion[,minorOSVersion]]".
+bool parseSubsystemOption(PECOFFTargetInfo &info, std::string arg,
+ raw_ostream &diagnostics) {
+ StringRef subsystemStr, osVersionStr;
+ llvm::tie(subsystemStr, osVersionStr) = StringRef(arg).split(',');
+
+ // Parse optional OS version if exists.
+ if (!osVersionStr.empty())
+ if (!parseMinOSVersion(info, osVersionStr, diagnostics))
+ return false;
+
+ // Parse subsystem name.
+ llvm::COFF::WindowsSubsystem subsystem = stringToWinSubsystem(subsystemStr);
+ if (subsystem == llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN) {
+ diagnostics << "error: unknown subsystem name: " << subsystemStr << "\n";
+ return false;
+ }
+ info.setSubsystem(subsystem);
+ return true;
+}
+
// Add ".obj" extension if the given path name has no file extension.
std::string canonicalizeInputFileName(std::string path) {
if (llvm::sys::path::extension(path).empty())
@@ -143,15 +196,9 @@ bool WinLinkDriver::parse(int argc, cons
}
// Handle -subsystem
- if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_subsystem)) {
- llvm::COFF::WindowsSubsystem subsystem = strToWinSubsystem(arg->getValue());
- if (subsystem == llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN) {
- diagnostics << "error: unknown subsystem name: "
- << arg->getValue() << "\n";
+ if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_subsystem))
+ if (!parseSubsystemOption(info, arg->getValue(), diagnostics))
return true;
- }
- info.setSubsystem(subsystem);
- }
// Hanlde -out
if (llvm::opt::Arg *outpath = parsedArgs->getLastArg(OPT_out))
Modified: lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp?rev=182988&r1=182987&r2=182988&view=diff
==============================================================================
--- lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp (original)
+++ lld/trunk/unittests/DriverTests/WinLinkDriverTest.cpp Fri May 31 01:30:10 2013
@@ -41,6 +41,8 @@ TEST_F(WinLinkParserTest, Basic) {
EXPECT_EQ("a.obj", inputFiles[0]);
EXPECT_EQ("b.obj", inputFiles[1]);
EXPECT_EQ("c.obj", inputFiles[2]);
+ EXPECT_EQ(6, info->getMinOSVersion().majorVersion);
+ EXPECT_EQ(0, info->getMinOSVersion().minorVersion);
}
TEST_F(WinLinkParserTest, WindowsStyleOption) {
@@ -66,4 +68,18 @@ TEST_F(WinLinkParserTest, NonStandardFil
EXPECT_EQ("foo.o", inputFiles[0]);
}
+TEST_F(WinLinkParserTest, MinMajorOSVersion) {
+ parse("link.exe", "-subsystem", "windows,3", "foo.o", nullptr);
+ EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, info->getSubsystem());
+ EXPECT_EQ(3, info->getMinOSVersion().majorVersion);
+ EXPECT_EQ(0, info->getMinOSVersion().minorVersion);
+}
+
+TEST_F(WinLinkParserTest, MinMajorMinorOSVersion) {
+ parse("link.exe", "-subsystem", "windows,3.1", "foo.o", nullptr);
+ EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI, info->getSubsystem());
+ EXPECT_EQ(3, info->getMinOSVersion().majorVersion);
+ EXPECT_EQ(1, info->getMinOSVersion().minorVersion);
+}
+
} // end anonymous namespace
More information about the llvm-commits
mailing list