[lld] r238564 - COFF: Add /machine option.
Rui Ueyama
ruiu at google.com
Fri May 29 09:06:00 PDT 2015
Author: ruiu
Date: Fri May 29 11:06:00 2015
New Revision: 238564
URL: http://llvm.org/viewvc/llvm-project?rev=238564&view=rev
Log:
COFF: Add /machine option.
Added:
lld/trunk/test/COFF/machine.test
Modified:
lld/trunk/COFF/Config.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/COFF/DriverUtils.cpp
lld/trunk/COFF/Writer.cpp
Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Fri May 29 11:06:00 2015
@@ -11,6 +11,7 @@
#define LLD_COFF_CONFIG_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/COFF.h"
#include <cstdint>
#include <set>
#include <string>
@@ -20,6 +21,7 @@ namespace coff {
class Configuration {
public:
+ llvm::COFF::MachineTypes MachineType = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
bool Verbose = false;
std::string EntryName = "mainCRTStartup";
uint64_t ImageBase = 0x140000000;
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri May 29 11:06:00 2015
@@ -103,11 +103,23 @@ bool link(int Argc, const char *Argv[])
llvm::errs() << "no input files.\n";
return false;
}
+
+ // Handle /verbose
if (Args->hasArg(OPT_verbose))
Config->Verbose = true;
+
+ // Handle /entry
if (auto *Arg = Args->getLastArg(OPT_entry))
Config->EntryName = Arg->getValue();
+ // Handle /machine
+ auto MTOrErr = getMachineType(Args.get());
+ if (auto EC = MTOrErr.getError()) {
+ llvm::errs() << EC.message() << "\n";
+ return false;
+ }
+ Config->MachineType = MTOrErr.get();
+
// Parse all input files and put all symbols to the symbol table.
// The symbol table will take care of name resolution.
SymbolTable Symtab;
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Fri May 29 11:06:00 2015
@@ -22,6 +22,7 @@
namespace lld {
namespace coff {
+using llvm::COFF::MachineTypes;
class InputFile;
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
@@ -37,6 +38,9 @@ std::error_code parseDirectives(StringRe
std::string findLib(StringRef Filename);
std::string findFile(StringRef Filename);
+// For /machine option.
+ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args);
+
// Create enum with OPT_xxx values for each option in Options.td
enum {
OPT_INVALID = 0,
Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Fri May 29 11:06:00 2015
@@ -87,6 +87,47 @@ std::string findFile(StringRef Filename)
return Filename;
}
+// Peeks at the file header to get architecture (e.g. i386 or AMD64).
+// Returns "unknown" if it's not a valid object file.
+static MachineTypes getFileMachineType(StringRef Path) {
+ file_magic Magic;
+ if (identify_magic(Path, Magic))
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+ if (Magic != file_magic::coff_object)
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path);
+ if (BufOrErr.getError())
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+ std::error_code EC;
+ llvm::object::COFFObjectFile Obj(BufOrErr.get()->getMemBufferRef(), EC);
+ if (EC)
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+ return static_cast<MachineTypes>(Obj.getMachine());
+}
+
+// Returns /machine's value.
+ErrorOr<MachineTypes> getMachineType(llvm::opt::InputArgList *Args) {
+ if (auto *Arg = Args->getLastArg(OPT_machine)) {
+ StringRef S(Arg->getValue());
+ MachineTypes MT = StringSwitch<MachineTypes>(S.lower())
+ .Case("arm", IMAGE_FILE_MACHINE_ARMNT)
+ .Case("x64", IMAGE_FILE_MACHINE_AMD64)
+ .Case("x86", IMAGE_FILE_MACHINE_I386)
+ .Default(IMAGE_FILE_MACHINE_UNKNOWN);
+ if (MT == IMAGE_FILE_MACHINE_UNKNOWN)
+ return make_dynamic_error_code("unknown /machine argument" + S);
+ return MT;
+ }
+ // If /machine option is missing, we need to take a look at
+ // the magic byte of the first object file to infer machine type.
+ for (auto *Arg : Args->filtered(OPT_INPUT)) {
+ MachineTypes MT = getFileMachineType(Arg->getValue());
+ if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
+ return MT;
+ }
+ return IMAGE_FILE_MACHINE_UNKNOWN;
+}
+
// Create OptTable
// Create prefix string literals used in Options.td
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=238564&r1=238563&r2=238564&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Fri May 29 11:06:00 2015
@@ -244,7 +244,7 @@ void Writer::writeHeader() {
// Write COFF header
auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
Buf += sizeof(*COFF);
- COFF->Machine = IMAGE_FILE_MACHINE_AMD64;
+ COFF->Machine = Config->MachineType;
COFF->NumberOfSections = OutputSections.size();
COFF->Characteristics =
(IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED |
Added: lld/trunk/test/COFF/machine.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/machine.test?rev=238564&view=auto
==============================================================================
--- lld/trunk/test/COFF/machine.test (added)
+++ lld/trunk/test/COFF/machine.test Fri May 29 11:06:00 2015
@@ -0,0 +1,11 @@
+# RUN: lld -flavor link2 /entry:main /machine:x64 /out:%t.exe \
+# RUN: %p/Inputs/ret42.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
+
+AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
+
+# RUN: lld -flavor link2 /entry:main /machine:x86 /out:%t.exe \
+# RUN: %p/Inputs/ret42.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
+
+I386: Machine: IMAGE_FILE_MACHINE_I386
More information about the llvm-commits
mailing list