forked from OSchip/llvm-project
[PECOFF][Driver] Add -stack command line option.
llvm-svn: 183604
This commit is contained in:
parent
7b5592bc0b
commit
eb0cc96e4b
|
@ -23,9 +23,17 @@ namespace lld {
|
|||
class PECOFFTargetInfo : public TargetInfo {
|
||||
public:
|
||||
PECOFFTargetInfo()
|
||||
: _subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN),
|
||||
: _stackReserve(1024 * 1024),
|
||||
_stackCommit(4096),
|
||||
_subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN),
|
||||
_minOSVersion(6, 0) {}
|
||||
|
||||
struct OSVersion {
|
||||
OSVersion(int v1, int v2) : majorVersion(v1), minorVersion(v2) {}
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
};
|
||||
|
||||
virtual error_code parseFile(
|
||||
std::unique_ptr<MemoryBuffer> &mb,
|
||||
std::vector<std::unique_ptr<File>> &result) const;
|
||||
|
@ -35,31 +43,21 @@ public:
|
|||
|
||||
virtual void addPasses(PassManager &pm) const {}
|
||||
|
||||
void setSubsystem(llvm::COFF::WindowsSubsystem subsystem) {
|
||||
_subsystem = subsystem;
|
||||
}
|
||||
void setStackReserve(uint64_t size) { _stackReserve = size; }
|
||||
uint64_t getStackReserve() const { return _stackReserve; }
|
||||
|
||||
llvm::COFF::WindowsSubsystem getSubsystem() const {
|
||||
return _subsystem;
|
||||
}
|
||||
void setStackCommit(uint64_t size) { _stackCommit = size; }
|
||||
uint64_t getStackCommit() const { return _stackCommit; }
|
||||
|
||||
void setSubsystem(llvm::COFF::WindowsSubsystem ss) { _subsystem = ss; }
|
||||
llvm::COFF::WindowsSubsystem getSubsystem() const { return _subsystem; }
|
||||
|
||||
void setMinOSVersion(const OSVersion &version) { _minOSVersion = version; }
|
||||
OSVersion getMinOSVersion() const { return _minOSVersion; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
StringRef allocateString(const StringRef &ref) {
|
||||
char *x = _extraStrings.Allocate<char>(ref.size() + 1);
|
||||
memcpy(x, ref.data(), ref.size());
|
||||
|
@ -68,6 +66,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
uint64_t _stackReserve;
|
||||
uint64_t _stackCommit;
|
||||
llvm::COFF::WindowsSubsystem _subsystem;
|
||||
OSVersion _minOSVersion;
|
||||
|
||||
|
|
|
@ -66,6 +66,35 @@ int findDoubleDash(int argc, const char *argv[]) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Displays error message if the given version does not match with
|
||||
// /^\d+$/.
|
||||
bool checkNumber(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;
|
||||
}
|
||||
|
||||
// Parse -stack command line option. The form of the option is
|
||||
// "-stack:stackReserveSize[,stackCommitSize]".
|
||||
bool parseStackOption(PECOFFTargetInfo &info, const StringRef &arg,
|
||||
raw_ostream &diagnostics) {
|
||||
StringRef reserve, commit;
|
||||
llvm::tie(reserve, commit) = arg.split(',');
|
||||
if (!checkNumber(reserve, "invalid stack size: ", diagnostics))
|
||||
return false;
|
||||
info.setStackReserve(atoi(reserve.str().c_str()));
|
||||
if (!commit.empty()) {
|
||||
if (!checkNumber(commit, "invalid stack size: ", diagnostics))
|
||||
return false;
|
||||
info.setStackCommit(atoi(commit.str().c_str()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns subsystem type for the given string.
|
||||
llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) {
|
||||
std::string arg(str.lower());
|
||||
|
@ -75,28 +104,15 @@ llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) {
|
|||
.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,
|
||||
bool parseMinOSVersion(PECOFFTargetInfo &info, const 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))
|
||||
if (!checkNumber(majorVersion, "invalid OS major version: ", diagnostics))
|
||||
return false;
|
||||
if (!checkOSVersion(minorVersion, "invalid OS minor version: ", diagnostics))
|
||||
if (!checkNumber(minorVersion, "invalid OS minor version: ", diagnostics))
|
||||
return false;
|
||||
PECOFFTargetInfo::OSVersion minOSVersion(atoi(majorVersion.str().c_str()),
|
||||
atoi(minorVersion.str().c_str()));
|
||||
|
@ -195,6 +211,11 @@ bool WinLinkDriver::parse(int argc, const char *argv[],
|
|||
info.appendLLVMOption((*it)->getValue());
|
||||
}
|
||||
|
||||
// Handle -stack
|
||||
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_stack))
|
||||
if (!parseStackOption(info, arg->getValue(), diagnostics))
|
||||
return true;
|
||||
|
||||
// Handle -subsystem
|
||||
if (llvm::opt::Arg *arg = parsedArgs->getLastArg(OPT_subsystem))
|
||||
if (!parseSubsystemOption(info, arg->getValue(), diagnostics))
|
||||
|
|
|
@ -9,6 +9,10 @@ def out : Separate<["-", "/"], "out">,
|
|||
HelpText<"Path to file to write output">;
|
||||
def out_c : Joined<["-", "/"], "out:">, Alias<out>;
|
||||
|
||||
def stack : Separate<["-", "/"], "stack">,
|
||||
HelpText<"Size of the stack">;
|
||||
def stack_c: Joined<["-", "/"], "stack:">, Alias<stack>;
|
||||
|
||||
def subsystem : Separate<["-", "/"], "subsystem">,
|
||||
HelpText<"Specify subsystem">;
|
||||
def subsystem_c: Joined<["-", "/"], "subsystem:">, Alias<subsystem>;
|
||||
|
|
|
@ -23,6 +23,13 @@ error_code PECOFFTargetInfo::parseFile(
|
|||
}
|
||||
|
||||
bool PECOFFTargetInfo::validate(raw_ostream &diagnostics) {
|
||||
if (_stackReserve < _stackCommit) {
|
||||
diagnostics << "Invalid stack size: reserve size must be equal to or "
|
||||
<< "greater than commit size, but got "
|
||||
<< _stackCommit << " and " << _stackReserve << ".\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
_reader = createReaderPECOFF(*this);
|
||||
_writer = createWriterPECOFF(*this);
|
||||
return false;
|
||||
|
|
|
@ -155,8 +155,8 @@ public:
|
|||
| llvm::COFF::IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
|
||||
| llvm::COFF::IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
|
||||
|
||||
_peHeader.SizeOfStackReserve = 0x100000;
|
||||
_peHeader.SizeOfStackCommit = 0x1000;
|
||||
_peHeader.SizeOfStackReserve = targetInfo.getStackReserve();
|
||||
_peHeader.SizeOfStackCommit = targetInfo.getStackCommit();
|
||||
_peHeader.SizeOfHeapReserve = 0x100000;
|
||||
_peHeader.SizeOfHeapCommit = 0x1000;
|
||||
|
||||
|
|
|
@ -44,6 +44,8 @@ TEST_F(WinLinkParserTest, Basic) {
|
|||
EXPECT_EQ("c.obj", inputFiles[2]);
|
||||
EXPECT_EQ(6, info->getMinOSVersion().majorVersion);
|
||||
EXPECT_EQ(0, info->getMinOSVersion().minorVersion);
|
||||
EXPECT_EQ(1024 * 1024, info->getStackReserve());
|
||||
EXPECT_EQ(4096, info->getStackCommit());
|
||||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, WindowsStyleOption) {
|
||||
|
@ -83,4 +85,15 @@ TEST_F(WinLinkParserTest, MinMajorMinorOSVersion) {
|
|||
EXPECT_EQ(1, info->getMinOSVersion().minorVersion);
|
||||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, StackReserve) {
|
||||
parse("link.exe", "-stack", "8192", nullptr);
|
||||
EXPECT_EQ(8192, info->getStackReserve());
|
||||
EXPECT_EQ(4096, info->getStackCommit());
|
||||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, StackReserveAndCommit) {
|
||||
parse("link.exe", "-stack", "16384,8192", nullptr);
|
||||
EXPECT_EQ(16384, info->getStackReserve());
|
||||
EXPECT_EQ(8192, info->getStackCommit());
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
|
Loading…
Reference in New Issue