[lld] r243188 - COFF: Don't assume !is64() means i386.

Rui Ueyama ruiu at google.com
Fri Jul 24 17:20:07 PDT 2015


Author: ruiu
Date: Fri Jul 24 19:20:06 2015
New Revision: 243188

URL: http://llvm.org/viewvc/llvm-project?rev=243188&view=rev
Log:
COFF: Don't assume !is64() means i386.

In many places we assumed that is64() means AMD64 and i386 otherwise.
This assumption is not sound because Windows also supports ARM.
The linker doesn't support ARM yet, but this is a first step.

Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/DLL.cpp
    lld/trunk/COFF/DLL.h
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/ModuleDef.cpp
    lld/trunk/COFF/SymbolTable.cpp

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Fri Jul 24 19:20:06 2015
@@ -252,17 +252,23 @@ ImportThunkChunk::ImportThunkChunk(Defin
 }
 
 void ImportThunkChunk::getBaserels(std::vector<uint32_t> *Res) {
-  if (!Config->is64())
+  if (Config->MachineType == I386)
     Res->push_back(getRVA() + 2);
 }
 
 void ImportThunkChunk::writeTo(uint8_t *Buf) {
   memcpy(Buf + FileOff, ImportThunkData, sizeof(ImportThunkData));
   // The first two bytes is a JMP instruction. Fill its operand.
-  uint32_t Operand = Config->is64()
-      ? ImpSymbol->getRVA() - RVA - getSize()
-      : ImpSymbol->getRVA() + Config->ImageBase;
-  write32le(Buf + FileOff + 2, Operand);
+  switch (Config->MachineType) {
+  case AMD64:
+    write32le(Buf + FileOff + 2, ImpSymbol->getRVA() - RVA - getSize());
+    break;
+  case I386:
+    write32le(Buf + FileOff + 2, ImpSymbol->getRVA() + Config->ImageBase);
+    break;
+  default:
+    llvm_unreachable("unsupported machine type");
+  }
 }
 
 void LocalImportChunk::getBaserels(std::vector<uint32_t> *Res) {
@@ -299,10 +305,17 @@ BaserelChunk::BaserelChunk(uint32_t Page
   write32le(P, Page);
   write32le(P + 4, Data.size());
   P += 8;
-  uint16_t RelTy =
-      Config->is64() ? IMAGE_REL_BASED_DIR64 : IMAGE_REL_BASED_HIGHLOW;
   for (uint32_t *I = Begin; I != End; ++I) {
-    write16le(P, (RelTy << 12) | (*I - Page));
+    switch (Config->MachineType) {
+    case AMD64:
+      write16le(P, (IMAGE_REL_BASED_DIR64 << 12) | (*I - Page));
+      break;
+    case I386:
+      write16le(P, (IMAGE_REL_BASED_HIGHLOW << 12) | (*I - Page));
+      break;
+    default:
+      llvm_unreachable("unsupported machine type");
+    }
     P += 2;
   }
 }

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Fri Jul 24 19:20:06 2015
@@ -21,6 +21,7 @@ namespace lld {
 namespace coff {
 
 using llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
+using llvm::COFF::IMAGE_FILE_MACHINE_I386;
 using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
 using llvm::COFF::WindowsSubsystem;
 using llvm::StringRef;
@@ -28,6 +29,11 @@ class DefinedAbsolute;
 class DefinedRelative;
 class Undefined;
 
+// Short aliases.
+static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
+static const auto ARM = llvm::COFF::IMAGE_FILE_MACHINE_ARM;
+static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
+
 // Represents an /export option.
 struct Export {
   StringRef Name;

Modified: lld/trunk/COFF/DLL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.cpp (original)
+++ lld/trunk/COFF/DLL.cpp Fri Jul 24 19:20:06 2015
@@ -391,12 +391,7 @@ void DelayLoadContents::create(Defined *
 
     size_t Base = Addresses.size();
     for (DefinedImportData *S : Syms) {
-      Chunk *T;
-      if (Config->is64()) {
-        T = new ThunkChunkX64(S, Dir.get(), Helper);
-      } else {
-        T = new ThunkChunkX86(S, Dir.get(), Helper);
-      }
+      Chunk *T = newThunkChunk(S, Dir.get());
       auto A = make_unique<DelayAddressChunk>(T);
       Addresses.push_back(std::move(A));
       Thunks.push_back(std::unique_ptr<Chunk>(T));
@@ -430,6 +425,17 @@ void DelayLoadContents::create(Defined *
       make_unique<NullChunk>(sizeof(delay_import_directory_table_entry)));
 }
 
+Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
+  switch (Config->MachineType) {
+  case AMD64:
+    return new ThunkChunkX64(S, Dir, Helper);
+  case I386:
+    return new ThunkChunkX86(S, Dir, Helper);
+  default:
+    llvm_unreachable("unsupported machine type");
+  }
+}
+
 // Export table
 // Read Microsoft PE/COFF spec 5.3 for details.
 

Modified: lld/trunk/COFF/DLL.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DLL.h?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/DLL.h (original)
+++ lld/trunk/COFF/DLL.h Fri Jul 24 19:20:06 2015
@@ -57,6 +57,8 @@ public:
   uint64_t getDirSize();
 
 private:
+  Chunk *newThunkChunk(DefinedImportData *S, Chunk *Dir);
+
   Defined *Helper;
   std::vector<DefinedImportData *> Imports;
   std::vector<std::unique_ptr<Chunk>> Dirs;

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Fri Jul 24 19:20:06 2015
@@ -108,7 +108,7 @@ LinkerDriver::parseDirectives(StringRef
       ErrorOr<Export> E = parseExport(Arg->getValue());
       if (auto EC = E.getError())
         return EC;
-      if (!Config->is64() && E->ExtName.startswith("_"))
+      if (Config->MachineType == I386 && E->ExtName.startswith("_"))
         E->ExtName = E->ExtName.substr(1);
       Config->Exports.push_back(E.get());
       break;
@@ -554,8 +554,8 @@ bool LinkerDriver::link(llvm::ArrayRef<c
   if (auto *Arg = Args.getLastArg(OPT_entry)) {
     Config->Entry = addUndefined(mangle(Arg->getValue()));
   } else if (Args.hasArg(OPT_dll) && !Config->NoEntry) {
-    StringRef S =
-        Config->is64() ? "_DllMainCRTStartup" : "__DllMainCRTStartup at 12";
+    StringRef S = (Config->MachineType == I386) ? "__DllMainCRTStartup at 12"
+                                                : "_DllMainCRTStartup";
     Config->Entry = addUndefined(S);
   } else if (!Config->NoEntry) {
     // Windows specific -- If entry point name is not given, we need to
@@ -575,7 +575,7 @@ bool LinkerDriver::link(llvm::ArrayRef<c
     ErrorOr<Export> E = parseExport(Arg->getValue());
     if (E.getError())
       return false;
-    if (!Config->is64() && !E->Name.startswith("_@?"))
+    if (Config->MachineType == I386 && !E->Name.startswith("_@?"))
       E->Name = mangle(E->Name);
     Config->Exports.push_back(E.get());
   }
@@ -595,10 +595,10 @@ bool LinkerDriver::link(llvm::ArrayRef<c
   // Handle /delayload
   for (auto *Arg : Args.filtered(OPT_delayload)) {
     Config->DelayLoads.insert(StringRef(Arg->getValue()).lower());
-    if (Config->is64()) {
-      Config->DelayLoadHelper = addUndefined("__delayLoadHelper2");
-    } else {
+    if (Config->MachineType == I386) {
       Config->DelayLoadHelper = addUndefined("___delayLoadHelper2 at 8");
+    } else {
+      Config->DelayLoadHelper = addUndefined("__delayLoadHelper2");
     }
   }
 

Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Fri Jul 24 19:20:06 2015
@@ -428,7 +428,7 @@ std::error_code fixupExports() {
     if (!E.ExtName.empty())
       continue;
     StringRef S = E.Sym->repl()->getName();
-    if (!Config->is64() && S.startswith("_"))
+    if (Config->MachineType == I386 && S.startswith("_"))
       S = S.substr(1);
     E.ExtName = S;
   }

Modified: lld/trunk/COFF/ModuleDef.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ModuleDef.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/ModuleDef.cpp (original)
+++ lld/trunk/COFF/ModuleDef.cpp Fri Jul 24 19:20:06 2015
@@ -209,7 +209,7 @@ private:
       unget();
     }
 
-    if (!Config->is64() && !E.Name.startswith("_@?"))
+    if (Config->MachineType == I386 && !E.Name.startswith("_@?"))
       E.Name = Alloc->save("_" + E.Name);
 
     for (;;) {

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=243188&r1=243187&r2=243188&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Fri Jul 24 19:20:06 2015
@@ -287,7 +287,7 @@ StringRef SymbolTable::findMangle(String
   if (Symbol *Sym = find(Name))
     if (!isa<Undefined>(Sym->Body))
       return Name;
-  if (Config->is64())
+  if (Config->MachineType != I386)
     return findByPrefix(("?" + Name + "@@Y").str());
   if (!Name.startswith("_"))
     return "";





More information about the llvm-commits mailing list