COFF: Fix export symbol names for x86.
authorRui Ueyama <ruiu@google.com>
Tue, 28 Jul 2015 22:34:24 +0000 (22:34 +0000)
committerRui Ueyama <ruiu@google.com>
Tue, 28 Jul 2015 22:34:24 +0000 (22:34 +0000)
I don't fully understand the rationale behind the name mangling
scheme used for the DLL export table and the import library.
Why only leading "_" is dropped for the import library while
both "_" and "@" are dropped from DLL symbol table? But this seems
to be what MSVC linker does.

llvm-svn: 243490

lld/COFF/Config.h
lld/COFF/DLL.cpp
lld/COFF/DriverUtils.cpp
lld/test/COFF/Inputs/export32.yaml [deleted file]
lld/test/COFF/export32.test

index bb093ab..8479491 100644 (file)
@@ -34,8 +34,10 @@ static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
 
 // Represents an /export option.
 struct Export {
-  StringRef Name;
-  StringRef ExtName;
+  StringRef Name;       // N in /export:N or /export:E=N
+  StringRef ExtName;    // E in /export:E=N
+  StringRef ExtDLLName; // Symbol name written to a DLL export table
+  StringRef ExtLibName; // Symbol name written to a import library
   Undefined *Sym = nullptr;
   uint16_t Ordinal = 0;
   bool Noname = false;
index 4bcec24..b6ba51b 100644 (file)
@@ -535,7 +535,7 @@ EdataContents::EdataContents() {
   std::vector<Chunk *> Names;
   for (Export &E : Config->Exports)
     if (!E.Noname)
-      Names.push_back(new StringChunk(E.ExtName));
+      Names.push_back(new StringChunk(E.ExtDLLName));
   auto *NameTab = new NamePointersChunk(Names);
   auto *OrdinalTab = new ExportOrdinalChunk(Names.size());
   auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName,
index 0dd59b6..79627ae 100644 (file)
@@ -425,12 +425,19 @@ std::error_code fixupExports() {
   }
 
   for (Export &E : Config->Exports) {
-    if (!E.ExtName.empty())
+    if (!E.ExtName.empty()) {
+      E.ExtDLLName = E.ExtName;
+      E.ExtLibName = E.ExtName;
       continue;
+    }
     StringRef S = E.Sym->repl()->getName();
-    if (Config->Machine == I386 && S.startswith("_"))
-      S = S.substr(1);
-    E.ExtName = S;
+    if (Config->Machine == I386 && S.startswith("_")) {
+      E.ExtDLLName = S.substr(1).split('@').first;
+      E.ExtLibName = S.substr(1);
+      continue;
+    }
+    E.ExtDLLName = S;
+    E.ExtLibName = S;
   }
 
   // Uniquefy by name.
@@ -452,9 +459,10 @@ std::error_code fixupExports() {
   Config->Exports = std::move(V);
 
   // Sort by name.
-  std::sort(
-      Config->Exports.begin(), Config->Exports.end(),
-      [](const Export &A, const Export &B) { return A.ExtName < B.ExtName; });
+  std::sort(Config->Exports.begin(), Config->Exports.end(),
+            [](const Export &A, const Export &B) {
+              return A.ExtDLLName < B.ExtDLLName;
+            });
   return std::error_code();
 }
 
@@ -528,7 +536,7 @@ static std::string createModuleDefinitionFile() {
   OS << "LIBRARY \"" << llvm::sys::path::filename(Config->OutputFile) << "\"\n"
      << "EXPORTS\n";
   for (Export &E : Config->Exports) {
-    OS << "  " << E.ExtName;
+    OS << "  " << E.ExtLibName;
     if (E.Ordinal > 0)
       OS << " @" << E.Ordinal;
     if (E.Noname)
diff --git a/lld/test/COFF/Inputs/export32.yaml b/lld/test/COFF/Inputs/export32.yaml
deleted file mode 100644 (file)
index 67379c1..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
----
-header:
-  Machine:         IMAGE_FILE_MACHINE_I386
-  Characteristics: []
-sections:
-  - Name:            .text
-    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
-    Alignment:       4
-    SectionData:     B800000000506800000000680000000050E80000000050E800000000
-  - Name:            .drectve
-    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
-    Alignment:       2147483648
-    SectionData:     2f6578706f72743a5f6578706f7274666e3300  # /export:_exportfn3
-symbols:
-  - Name:            .text
-    Value:           0
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_STATIC
-    SectionDefinition:
-      Length:          28
-      NumberOfRelocations: 4
-      NumberOfLinenumbers: 0
-      CheckSum:        0
-      Number:          0
-  - Name:            __DllMainCRTStartup@12
-    Value:           0
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
-  - Name:            _exportfn1
-    Value:           8
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
-  - Name:            _exportfn2
-    Value:           16
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
-  - Name:            _exportfn3
-    Value:           16
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
-  - Name:            '?mangled@@YAHXZ'
-    Value:           16
-    SectionNumber:   1
-    SimpleType:      IMAGE_SYM_TYPE_NULL
-    ComplexType:     IMAGE_SYM_DTYPE_NULL
-    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
-...
index dc01484..62ee1a6 100644 (file)
-# RUN: yaml2obj < %p/Inputs/export32.yaml > %t.obj
+# RUN: yaml2obj < %s > %t.obj
 #
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
 
-CHECK1:      Export Table:
-CHECK1:      DLL name: export32.test.tmp.dll
-CHECK1:      Ordinal      RVA  Name
-CHECK1-NEXT:       0        0
-CHECK1-NEXT:       1   0x1008  exportfn1
-CHECK1-NEXT:       2   0x1010  exportfn2
+CHECK1:      Export Table:
+CHECK1:      DLL name: export32.test.tmp.dll
+CHECK1:      Ordinal      RVA  Name
+CHECK1-NEXT:       0        0
+CHECK1-NEXT:       1   0x1008  exportfn1
+CHECK1-NEXT:       2   0x1010  exportfn2
 
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
 # RUN:   /export:exportfn2 /export:mangled
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
 
-CHECK2:      Export Table:
-CHECK2:      DLL name: export32.test.tmp.dll
-CHECK2:      Ordinal      RVA  Name
-CHECK2-NEXT:       0        0
-CHECK2-NEXT:       1        0
-CHECK2-NEXT:       2        0
-CHECK2-NEXT:       3        0
-CHECK2-NEXT:       4        0
-CHECK2-NEXT:       5   0x1008  exportfn1
-CHECK2-NEXT:       6   0x1010  ?mangled@@YAHXZ
-CHECK2-NEXT:       7   0x1010  exportfn2
-CHECK2-NEXT:       8   0x1010  exportfn3
+CHECK2:      Export Table:
+CHECK2:      DLL name: export32.test.tmp.dll
+CHECK2:      Ordinal      RVA  Name
+CHECK2-NEXT:       0        0
+CHECK2-NEXT:       1        0
+CHECK2-NEXT:       2        0
+CHECK2-NEXT:       3        0
+CHECK2-NEXT:       4        0
+CHECK2-NEXT:       5   0x1008  exportfn1
+CHECK2-NEXT:       6   0x1010  ?mangled@@YAHXZ
+CHECK2-NEXT:       7   0x1010  exportfn2
+CHECK2-NEXT:       8   0x1010  exportfn3
 
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s
 
-CHECK3:      Export Table:
-CHECK3:      DLL name: export32.test.tmp.dll
-CHECK3:      Ordinal      RVA  Name
-CHECK3-NEXT:       0        0
-CHECK3-NEXT:       1        0
-CHECK3-NEXT:       2        0
-CHECK3-NEXT:       3        0
-CHECK3-NEXT:       4        0
-CHECK3-NEXT:       5   0x1008
-CHECK3-NEXT:       6   0x1010  exportfn2
+CHECK3:      Export Table:
+CHECK3:      DLL name: export32.test.tmp.dll
+CHECK3:      Ordinal      RVA  Name
+CHECK3-NEXT:       0        0
+CHECK3-NEXT:       1        0
+CHECK3-NEXT:       2        0
+CHECK3-NEXT:       3        0
+CHECK3-NEXT:       4        0
+CHECK3-NEXT:       5   0x1008
+CHECK3-NEXT:       6   0x1010  exportfn2
 
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s
 
-CHECK4:      Export Table:
-CHECK4:      DLL name: export32.test.tmp.dll
-CHECK4:      Ordinal      RVA  Name
-CHECK4-NEXT:       0        0
-CHECK4-NEXT:       1   0x1010  exportfn3
-CHECK4-NEXT:       2   0x1008  f1
-CHECK4-NEXT:       3   0x1010  f2
+CHECK4:      Export Table:
+CHECK4:      DLL name: export32.test.tmp.dll
+CHECK4:      Ordinal      RVA  Name
+CHECK4-NEXT:       0        0
+CHECK4-NEXT:       1   0x1010  exportfn3
+CHECK4-NEXT:       2   0x1008  f1
+CHECK4-NEXT:       3   0x1010  f2
 
 # RUN: echo "EXPORTS exportfn1 @3" > %t.def
 # RUN: echo "fn2=exportfn2 @2" >> %t.def
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /def:%t.def
 # RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
 
-CHECK5:      Export Table:
-CHECK5:      DLL name: export32.test.tmp.dll
-CHECK5:      Ordinal      RVA  Name
-CHECK5-NEXT:       0        0
-CHECK5-NEXT:       1        0
-CHECK5-NEXT:       2   0x1010  fn2
-CHECK5-NEXT:       3   0x1008  exportfn1
-CHECK5-NEXT:       4   0x1010  exportfn3
+CHECK5:      Export Table:
+CHECK5:      DLL name: export32.test.tmp.dll
+CHECK5:      Ordinal      RVA  Name
+CHECK5-NEXT:       0        0
+CHECK5-NEXT:       1        0
+CHECK5-NEXT:       2   0x1010  fn2
+CHECK5-NEXT:       3   0x1008  exportfn1
+CHECK5-NEXT:       4   0x1010  exportfn3
 
 # RUN: lld -flavor link2 /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
 # RUN:   /export:exportfn1 /export:exportfn2,@5 >& %t.log
 # RUN: FileCheck -check-prefix=CHECK6 %s < %t.log
 
-CHECK6:     duplicate /export option: _exportfn2
-CHECK6-NOT: duplicate /export option: _exportfn1
+# CHECK6:     duplicate /export option: _exportfn2
+# CHECK6-NOT: duplicate /export option: _exportfn1
+
+---
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     B800000000506800000000680000000050E80000000050E800000000
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       2147483648
+    SectionData:     2f6578706f72743a5f6578706f7274666e3300  # /export:_exportfn3
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          28
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            __DllMainCRTStartup@12
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _exportfn1
+    Value:           8
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _exportfn2@4
+    Value:           16
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            _exportfn3
+    Value:           16
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            '?mangled@@YAHXZ'
+    Value:           16
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...