forked from OSchip/llvm-project
[PECOFF] Add a field for machine type to PECOFFLinkingContext.
So that we can determine what the target architecture is. Adding this field does not mean that we are going to support non-i386 architectures soon; there are many things to do to support them, and I'm focusing on i386 now. But this is the first step toward multi architecture support. llvm-svn: 190627
This commit is contained in:
parent
9063bf462a
commit
98896ed1b5
|
@ -20,6 +20,9 @@
|
|||
#include "llvm/Support/COFF.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using llvm::COFF::MachineTypes;
|
||||
using llvm::COFF::WindowsSubsystem;
|
||||
|
||||
namespace lld {
|
||||
|
||||
class PECOFFLinkingContext : public LinkingContext {
|
||||
|
@ -27,8 +30,9 @@ public:
|
|||
PECOFFLinkingContext()
|
||||
: _baseAddress(0x400000), _stackReserve(1024 * 1024), _stackCommit(4096),
|
||||
_heapReserve(1024 * 1024), _heapCommit(4096),
|
||||
_subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN), _minOSVersion(6, 0),
|
||||
_nxCompat(true), _largeAddressAware(false),
|
||||
_subsystem(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN),
|
||||
_machineType(llvm::COFF::IMAGE_FILE_MACHINE_I386),
|
||||
_minOSVersion(6, 0), _nxCompat(true), _largeAddressAware(false),
|
||||
_baseRelocationEnabled(true), _terminalServerAware(true),
|
||||
_dynamicBaseEnabled(true), _imageType(ImageType::IMAGE_EXE) {
|
||||
setDeadStripping(true);
|
||||
|
@ -98,8 +102,11 @@ public:
|
|||
uint64_t getHeapReserve() const { return _heapReserve; }
|
||||
uint64_t getHeapCommit() const { return _heapCommit; }
|
||||
|
||||
void setSubsystem(llvm::COFF::WindowsSubsystem ss) { _subsystem = ss; }
|
||||
llvm::COFF::WindowsSubsystem getSubsystem() const { return _subsystem; }
|
||||
void setSubsystem(WindowsSubsystem ss) { _subsystem = ss; }
|
||||
WindowsSubsystem getSubsystem() const { return _subsystem; }
|
||||
|
||||
void setMachineType(MachineTypes type) { _machineType = type; }
|
||||
MachineTypes getMachineType() const { return _machineType; }
|
||||
|
||||
void setMinOSVersion(const OSVersion &version) { _minOSVersion = version; }
|
||||
OSVersion getMinOSVersion() const { return _minOSVersion; }
|
||||
|
@ -154,7 +161,8 @@ private:
|
|||
uint64_t _stackCommit;
|
||||
uint64_t _heapReserve;
|
||||
uint64_t _heapCommit;
|
||||
llvm::COFF::WindowsSubsystem _subsystem;
|
||||
WindowsSubsystem _subsystem;
|
||||
MachineTypes _machineType;
|
||||
OSVersion _minOSVersion;
|
||||
bool _nxCompat;
|
||||
bool _largeAddressAware;
|
||||
|
|
|
@ -116,6 +116,15 @@ llvm::COFF::WindowsSubsystem stringToWinSubsystem(StringRef str) {
|
|||
.Default(llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN);
|
||||
}
|
||||
|
||||
llvm::COFF::MachineTypes stringToMachineType(StringRef str) {
|
||||
return llvm::StringSwitch<llvm::COFF::MachineTypes>(str.lower())
|
||||
.Case("arm", llvm::COFF::IMAGE_FILE_MACHINE_ARM)
|
||||
.Case("ebc", llvm::COFF::IMAGE_FILE_MACHINE_EBC)
|
||||
.Case("x64", llvm::COFF::IMAGE_FILE_MACHINE_AMD64)
|
||||
.Case("x86", llvm::COFF::IMAGE_FILE_MACHINE_I386)
|
||||
.Default(llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN);
|
||||
}
|
||||
|
||||
// Handle /failifmatch option.
|
||||
bool handleFailIfMismatchOption(StringRef option,
|
||||
std::map<StringRef, StringRef> &mustMatch,
|
||||
|
@ -308,12 +317,13 @@ bool WinLinkDriver::parse(int argc, const char *argv[], PECOFFLinkingContext &ct
|
|||
break;
|
||||
}
|
||||
case OPT_machine: {
|
||||
StringRef platform = inputArg->getValue();
|
||||
if (!platform.equals_lower("x64")) {
|
||||
diagnostics << "error: LLD does not support non-x64 platform, "
|
||||
<< "but got /machine:" << platform << "\n";
|
||||
StringRef arg = inputArg->getValue();
|
||||
llvm::COFF::MachineTypes type = stringToMachineType(arg);
|
||||
if (type == llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
diagnostics << "error: unknown machine type: " << arg << "\n";
|
||||
return true;
|
||||
}
|
||||
ctx.setMachineType(type);
|
||||
break;
|
||||
}
|
||||
case OPT_subsystem: {
|
||||
|
|
|
@ -55,6 +55,12 @@ bool PECOFFLinkingContext::validateImpl(raw_ostream &diagnostics) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Architectures other than i386 is not supported yet.
|
||||
if (_machineType != llvm::COFF::IMAGE_FILE_MACHINE_I386) {
|
||||
diagnostics << "Machine type other than x86 is not supported.\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
_reader = createReaderPECOFF(*this);
|
||||
_writer = createWriterPECOFF(*this);
|
||||
return false;
|
||||
|
|
|
@ -145,7 +145,7 @@ public:
|
|||
std::memset(&_coffHeader, 0, sizeof(_coffHeader));
|
||||
std::memset(&_peHeader, 0, sizeof(_peHeader));
|
||||
|
||||
_coffHeader.Machine = llvm::COFF::IMAGE_FILE_MACHINE_I386;
|
||||
_coffHeader.Machine = context.getMachineType();
|
||||
_coffHeader.TimeDateStamp = time(NULL);
|
||||
|
||||
// The size of PE header including optional data directory is always 224.
|
||||
|
|
|
@ -34,6 +34,7 @@ TEST_F(WinLinkParserTest, Basic) {
|
|||
EXPECT_FALSE(parse("link.exe", "/subsystem:console", "/out:a.exe",
|
||||
"-entry:start", "a.obj", "b.obj", "c.obj", nullptr));
|
||||
EXPECT_EQ(llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI, _context.getSubsystem());
|
||||
EXPECT_EQ(llvm::COFF::IMAGE_FILE_MACHINE_I386, _context.getMachineType());
|
||||
EXPECT_EQ("a.exe", _context.outputPath());
|
||||
EXPECT_EQ("_start", _context.entrySymbolName());
|
||||
EXPECT_EQ(3, inputFileCount());
|
||||
|
@ -107,11 +108,7 @@ TEST_F(WinLinkParserTest, Libpath) {
|
|||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, MachineX64) {
|
||||
EXPECT_FALSE(parse("link.exe", "/machine:x64", "a.obj", nullptr));
|
||||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, MachineArm) {
|
||||
EXPECT_TRUE(parse("link.exe", "/machine:arm", "a.obj", nullptr));
|
||||
EXPECT_TRUE(parse("link.exe", "/machine:x64", "a.obj", nullptr));
|
||||
}
|
||||
|
||||
TEST_F(WinLinkParserTest, MinMajorOSVersion) {
|
||||
|
|
Loading…
Reference in New Issue