[lld] r241771 - COFF: Fix import thunks and name mangling for x86.

Rui Ueyama ruiu at google.com
Wed Jul 8 18:25:49 PDT 2015


Author: ruiu
Date: Wed Jul  8 20:25:49 2015
New Revision: 241771

URL: http://llvm.org/viewvc/llvm-project?rev=241771&view=rev
Log:
COFF: Fix import thunks and name mangling for x86.

With this patch, LLD is now able to correctly link a "hello world"
program written in assembly for 32-bit x86.

Added:
    lld/trunk/test/COFF/hello32.test
Removed:
    lld/trunk/test/COFF/imports32.test
Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/machine.test

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=241771&r1=241770&r2=241771&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Wed Jul  8 20:25:49 2015
@@ -245,7 +245,9 @@ ImportThunkChunk::ImportThunkChunk(Defin
 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 = ImpSymbol->getRVA() - RVA - getSize();
+  uint32_t Operand = Config->is64()
+      ? ImpSymbol->getRVA() - RVA - getSize()
+      : ImpSymbol->getRVA() + Config->ImageBase;
   write32le(Buf + FileOff + 2, Operand);
 }
 

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=241771&r1=241770&r2=241771&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Wed Jul  8 20:25:49 2015
@@ -207,6 +207,13 @@ Undefined *LinkerDriver::addUndefined(St
   return U;
 }
 
+// Symbol names are mangled by appending "_" prefix on x86.
+StringRef LinkerDriver::mangle(StringRef Sym) {
+  if (Config->MachineType == IMAGE_FILE_MACHINE_I386)
+    return Alloc.save("_" + Sym);
+  return Sym;
+}
+
 // Windows specific -- find default entry point name.
 StringRef LinkerDriver::findDefaultEntry() {
   // User-defined main functions and their corresponding entry points.
@@ -217,9 +224,9 @@ StringRef LinkerDriver::findDefaultEntry
       {"wWinMain", "wWinMainCRTStartup"},
   };
   for (auto E : Entries) {
-    Symbol *Sym = Symtab.find(E[0]);
+    Symbol *Sym = Symtab.find(mangle(E[0]));
     if (Sym && !isa<Undefined>(Sym->Body))
-      return E[1];
+      return mangle(E[1]);
   }
   return "";
 }
@@ -227,9 +234,9 @@ StringRef LinkerDriver::findDefaultEntry
 WindowsSubsystem LinkerDriver::inferSubsystem() {
   if (Config->DLL)
     return IMAGE_SUBSYSTEM_WINDOWS_GUI;
-  if (Symtab.find("main") || Symtab.find("wmain"))
+  if (Symtab.find(mangle("main")) || Symtab.find(mangle("wmain")))
     return IMAGE_SUBSYSTEM_WINDOWS_CUI;
-  if (Symtab.find("WinMain") || Symtab.find("wWinMain"))
+  if (Symtab.find(mangle("WinMain")) || Symtab.find(mangle("wWinMain")))
     return IMAGE_SUBSYSTEM_WINDOWS_GUI;
   return IMAGE_SUBSYSTEM_UNKNOWN;
 }
@@ -287,7 +294,7 @@ bool LinkerDriver::link(llvm::ArrayRef<c
 
   // Handle /entry
   if (auto *Arg = Args.getLastArg(OPT_entry))
-    Config->Entry = addUndefined(Arg->getValue());
+    Config->Entry = addUndefined(mangle(Arg->getValue()));
 
   // Handle /debug
   if (Args.hasArg(OPT_debug))
@@ -535,7 +542,7 @@ bool LinkerDriver::link(llvm::ArrayRef<c
     OwningMBs.push_back(std::move(MB)); // take ownership
   }
 
-  Symtab.addAbsolute("__ImageBase", Config->ImageBase);
+  Symtab.addAbsolute(mangle("__ImageBase"), Config->ImageBase);
 
   // Read all input files given via the command line. Note that step()
   // doesn't read files that are specified by directive sections.

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=241771&r1=241770&r2=241771&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Wed Jul  8 20:25:49 2015
@@ -93,6 +93,7 @@ private:
   std::set<std::string> VisitedFiles;
 
   Undefined *addUndefined(StringRef Sym);
+  StringRef mangle(StringRef Sym);
 
   // Windows specific -- "main" is not the only main function in Windows.
   // You can choose one from these four -- {w,}{WinMain,main}.

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=241771&r1=241770&r2=241771&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Jul  8 20:25:49 2015
@@ -395,8 +395,11 @@ template <typename PEHeaderTy> void Writ
   COFF->Machine = Config->MachineType;
   COFF->NumberOfSections = OutputSections.size();
   COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
-  if (Is64)
+  if (Is64) {
     COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
+  } else {
+    COFF->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
+  }
   if (Config->DLL)
     COFF->Characteristics |= IMAGE_FILE_DLL;
   if (!Config->Relocatable)

Added: lld/trunk/test/COFF/hello32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/hello32.test?rev=241771&view=auto
==============================================================================
--- lld/trunk/test/COFF/hello32.test (added)
+++ lld/trunk/test/COFF/hello32.test Wed Jul  8 20:25:49 2015
@@ -0,0 +1,118 @@
+# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
+# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \
+# RUN:   /entry:_main at 0 /out:%t.exe
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
+
+HEADER:      Format: COFF-i386
+HEADER-NEXT: Arch: i386
+HEADER-NEXT: AddressSize: 32bit
+HEADER-NEXT: ImageFileHeader {
+HEADER-NEXT:   Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
+HEADER-NEXT:   SectionCount: 3
+HEADER-NEXT:   TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+HEADER-NEXT:   PointerToSymbolTable: 0x0
+HEADER-NEXT:   SymbolCount: 0
+HEADER-NEXT:   OptionalHeaderSize: 224
+HEADER-NEXT:   Characteristics [ (0x102)
+HEADER-NEXT:     IMAGE_FILE_32BIT_MACHINE (0x100)
+HEADER-NEXT:     IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
+HEADER-NEXT:   ]
+HEADER-NEXT: }
+HEADER-NEXT: ImageOptionalHeader {
+HEADER-NEXT:   MajorLinkerVersion: 0
+HEADER-NEXT:   MinorLinkerVersion: 0
+HEADER-NEXT:   SizeOfCode: 512
+HEADER-NEXT:   SizeOfInitializedData: 1024
+HEADER-NEXT:   SizeOfUninitializedData: 0
+HEADER-NEXT:   AddressOfEntryPoint: 0x2000
+HEADER-NEXT:   BaseOfCode: 0x2000
+HEADER-NEXT:   BaseOfData: 0x0
+HEADER-NEXT:   ImageBase: 0x40000000
+HEADER-NEXT:   SectionAlignment: 4096
+HEADER-NEXT:   FileAlignment: 512
+HEADER-NEXT:   MajorOperatingSystemVersion: 6
+HEADER-NEXT:   MinorOperatingSystemVersion: 0
+HEADER-NEXT:   MajorImageVersion: 0
+HEADER-NEXT:   MinorImageVersion: 0
+HEADER-NEXT:   MajorSubsystemVersion: 6
+HEADER-NEXT:   MinorSubsystemVersion: 0
+HEADER-NEXT:   SizeOfImage: 16384
+HEADER-NEXT:   SizeOfHeaders: 4096
+HEADER-NEXT:   Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
+HEADER-NEXT:   Characteristics [ (0x8160)
+HEADER-NEXT:     IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40)
+HEADER-NEXT:     IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA (0x20)
+HEADER-NEXT:     IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100)
+HEADER-NEXT:     IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000)
+HEADER-NEXT:   ]
+HEADER-NEXT:   SizeOfStackReserve: 1048576
+HEADER-NEXT:   SizeOfStackCommit: 4096
+HEADER-NEXT:   SizeOfHeapReserve: 1048576
+HEADER-NEXT:   SizeOfHeapCommit: 4096
+HEADER-NEXT:   NumberOfRvaAndSize: 16
+HEADER-NEXT:   DataDirectory {
+HEADER-NEXT:     ExportTableRVA: 0x0
+HEADER-NEXT:     ExportTableSize: 0x0
+HEADER-NEXT:     ImportTableRVA: 0x3000
+HEADER-NEXT:     ImportTableSize: 0x28
+HEADER-NEXT:     ResourceTableRVA: 0x0
+HEADER-NEXT:     ResourceTableSize: 0x0
+HEADER-NEXT:     ExceptionTableRVA: 0x0
+HEADER-NEXT:     ExceptionTableSize: 0x0
+HEADER-NEXT:     CertificateTableRVA: 0x0
+HEADER-NEXT:     CertificateTableSize: 0x0
+HEADER-NEXT:     BaseRelocationTableRVA: 0x0
+HEADER-NEXT:     BaseRelocationTableSize: 0x0
+HEADER-NEXT:     DebugRVA: 0x0
+HEADER-NEXT:     DebugSize: 0x0
+HEADER-NEXT:     ArchitectureRVA: 0x0
+HEADER-NEXT:     ArchitectureSize: 0x0
+HEADER-NEXT:     GlobalPtrRVA: 0x0
+HEADER-NEXT:     GlobalPtrSize: 0x0
+HEADER-NEXT:     TLSTableRVA: 0x0
+HEADER-NEXT:     TLSTableSize: 0x0
+HEADER-NEXT:     LoadConfigTableRVA: 0x0
+HEADER-NEXT:     LoadConfigTableSize: 0x0
+HEADER-NEXT:     BoundImportRVA: 0x0
+HEADER-NEXT:     BoundImportSize: 0x0
+HEADER-NEXT:     IATRVA: 0x3034
+HEADER-NEXT:     IATSize: 0xC
+HEADER-NEXT:     DelayImportDescriptorRVA: 0x0
+HEADER-NEXT:     DelayImportDescriptorSize: 0x0
+HEADER-NEXT:     CLRRuntimeHeaderRVA: 0x0
+HEADER-NEXT:     CLRRuntimeHeaderSize: 0x0
+HEADER-NEXT:     ReservedRVA: 0x0
+HEADER-NEXT:     ReservedSize: 0x0
+HEADER-NEXT:   }
+HEADER-NEXT: }
+HEADER-NEXT: DOSHeader {
+HEADER-NEXT:   Magic: MZ
+HEADER-NEXT:   UsedBytesInTheLastPage: 0
+HEADER-NEXT:   FileSizeInPages: 0
+HEADER-NEXT:   NumberOfRelocationItems: 0
+HEADER-NEXT:   HeaderSizeInParagraphs: 0
+HEADER-NEXT:   MinimumExtraParagraphs: 0
+HEADER-NEXT:   MaximumExtraParagraphs: 0
+HEADER-NEXT:   InitialRelativeSS: 0
+HEADER-NEXT:   InitialSP: 0
+HEADER-NEXT:   Checksum: 0
+HEADER-NEXT:   InitialIP: 0
+HEADER-NEXT:   InitialRelativeCS: 0
+HEADER-NEXT:   AddressOfRelocationTable: 64
+HEADER-NEXT:   OverlayNumber: 0
+HEADER-NEXT:   OEMid: 0
+HEADER-NEXT:   OEMinfo: 0
+HEADER-NEXT:   AddressOfNewExeHeader: 64
+HEADER-NEXT: }
+
+IMPORTS: Format: COFF-i386
+IMPORTS: Arch: i386
+IMPORTS: AddressSize: 32bit
+IMPORTS: Import {
+IMPORTS:   Name: std32.dll
+IMPORTS:   ImportLookupTableRVA: 0x3028
+IMPORTS:   ImportAddressTableRVA: 0x3034
+IMPORTS:   Symbol: ExitProcess (0)
+IMPORTS:   Symbol: MessageBoxA (1)
+IMPORTS: }

Removed: lld/trunk/test/COFF/imports32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/imports32.test?rev=241770&view=auto
==============================================================================
--- lld/trunk/test/COFF/imports32.test (original)
+++ lld/trunk/test/COFF/imports32.test (removed)
@@ -1,15 +0,0 @@
-# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
-# RUN: lld -flavor link2 %t.obj %p/Inputs/std32.lib /subsystem:console \
-# RUN:   /entry:_main at 0 /out:%t.exe
-# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
-
-CHECK: Format: COFF-i386
-CHECK: Arch: i386
-CHECK: AddressSize: 32bit
-CHECK: Import {
-CHECK:   Name: std32.dll
-CHECK:   ImportLookupTableRVA: 0x3028
-CHECK:   ImportAddressTableRVA: 0x3034
-CHECK:   Symbol: ExitProcess (0)
-CHECK:   Symbol: MessageBoxA (1)
-CHECK: }

Modified: lld/trunk/test/COFF/machine.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/machine.test?rev=241771&r1=241770&r2=241771&view=diff
==============================================================================
--- lld/trunk/test/COFF/machine.test (original)
+++ lld/trunk/test/COFF/machine.test Wed Jul  8 20:25:49 2015
@@ -11,14 +11,14 @@
 # RUN: lld -flavor link2 /entry:main /subsystem:console /out:%t.exe %t.obj
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
 # RUN: lld -flavor link2 /entry:main /subsystem:console /machine:x86 \
-# RUN:   /out:%t.exe %t.obj
+# RUN:   /out:%t.exe %t.obj /fixed
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
 
 # I386: Machine: IMAGE_FILE_MACHINE_I386
 
 # RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_AMD64/ %s | yaml2obj > %t.obj
 # RUN: not lld -flavor link2 /entry:main /subsystem:console /machine:x86 \
-# RUN:   /out:%t.exe %t.obj >& %t.log
+# RUN:   /out:%t.exe %t.obj /fixed >& %t.log
 # RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log
 
 # RUN: sed -e s/MACHINETYPE/IMAGE_FILE_MACHINE_I386/ %s | yaml2obj > %t1.obj





More information about the llvm-commits mailing list