[LLVMdev] [PATCH] MCJIT/ELF should support MSVC C++ mangled symbols

Benoit Belley Benoit.Belley at autodesk.com
Wed Dec 10 09:15:22 PST 2014


Hi everyone,

We have found a problem while using the MCJIT engine on Windows. Our jitted code is invoking some external C++ functions. These external functions have names  that are mangled using the MSVC C++ naming convention. These were not handled properly by the ELObjectWriter.

The attached patch addresses this issue. The patch is against the LLVM release_35 branch (Revision 223459). The patch also includes a regression test.

We have successfully ran all LLVM & Clang regression tests after applying the patch on both Debug+Assert and Release builds.

Regards,
Benoit

------

The ELF format is used on Windows by the MCJIT engine.
Thus, on Windows, the ELFObjectWriter can encounter symbols mangled
using the MS Visual Studio C++ name mangling. Symbols mangled using the
MSVC C++ name mangling can legally have "@@@" as a substring. The
EFLObjectWriter should not interpret the "@@@" substring as specifying
GNU-style symbol versioning. The ELFObjectWriter therefore check for
the MSVC C++ name mangling prefix which is either "?", "@?", "__imp_?"
or "__imp_?@".

---
 lib/MC/ELFObjectWriter.cpp | 38 +++++++++++++++++++++++------
 test/MC/ELF/symver-msvc.s  | 60 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 7 deletions(-)
 create mode 100644 test/MC/ELF/symver-msvc.s

diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 5779b27..9fddca5 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -1051,14 +1051,38 @@ ELFObjectWriter::computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,

     // The @@@ in symbol version is replaced with @ in undefined symbols and
     // @@ in defined ones.
+    //
+    // We have to be careful though:
+    //
+    // The ELF format is used on Windows by the MCJIT engine.  Thus, on
+    // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
+    // Visual Studio C++ name mangling. Symbols mangled using the MSVC C++
+    // name mangling can legally have "@@@" as a sub-string. The
+    // EFLObjectWriter should not interpret the "@@@" sub-string as specifying
+    // GNU-style symbol versioning. The ELFObjectWriter therefore check for
+    // the MSVC C++ name mangling prefix which is either "?", "@?", "__imp_?"
+    // or "__imp_@?".
+    //
+    // It would have been interesting to be able to perform this ms mangling
+    // prefix check only when the target triple is of the form *-pc-windows-elf
+    // but it seems that this information is not easily accessible from the
+    // ELFObjectWriter.
     StringRef Name = Symbol.getName();
-    SmallString<32> Buf;
-    size_t Pos = Name.find("@@@");
-    if (Pos != StringRef::npos) {
-      Buf += Name.substr(0, Pos);
-      unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
-      Buf += Name.substr(Pos + Skip);
-      Name = Buf;
+    if (   !Name.startswith("?")
+        && !Name.startswith("@?")
+        && !Name.startswith("__imp_?")
+        && !Name.startswith("__imp_@?")) {
+      // This symbol isn't following the MSVC C++ name mangling convention. We
+      // can thus safely interpret the @@@ in symbol names as specifying
+      // symbol versioning.
+      SmallString<32> Buf;
+      size_t Pos = Name.find("@@@");
+      if (Pos != StringRef::npos) {
+        Buf += Name.substr(0, Pos);
+        unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
+        Buf += Name.substr(Pos + Skip);
+        Name = Buf;
+      }
     }
     MSD.Name = StrTabBuilder.add(Name);

diff --git a/test/MC/ELF/symver-msvc.s b/test/MC/ELF/symver-msvc.s
new file mode 100644
index 0000000..4a40791
--- /dev/null
+++ b/test/MC/ELF/symver-msvc.s
@@ -0,0 +1,60 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-windows-elf %s -o - | llvm-readobj -r -t | FileCheck %s
+
+// Verify that MSVC C++ mangled symbol are not affected by the
+// ELF symbol versioning. The ELF format is used on Windows by the
+// MCJIT execution engine.
+
+
+        .long "??_R0?AVexception at std@@@8"
+        .long "@??_R0?AVinvalid_argument at std@@@8"
+        .long "__imp_??_R0?AVlogic_error at std@@@8"
+        .long "__imp_@??_R0PAVexception at std@@@8"
+
+
+// CHECK:       Relocations [
+// CHECK-NEXT:    Section (2) .rela.text {
+// CHECK-NEXT:      0x0 R_X86_64_32 ??_R0?AVexception at std@@@8 0x0
+// CHECK-NEXT:      0x4 R_X86_64_32 @??_R0?AVinvalid_argument at std@@@8 0x0
+// CHECK-NEXT:      0x8 R_X86_64_32 __imp_??_R0?AVlogic_error at std@@@8 0x0
+// CHECK-NEXT:      0xC R_X86_64_32 __imp_@??_R0PAVexception at std@@@8 0x0
+// CHECK-NEXT:    }
+// CHECK-NEXT:  ]
+
+// CHECK:       Symbols [
+// CHECK:         Symbol {
+// CHECK:           Name: ??_R0?AVexception at std@@@8 (102)
+// CHECK-NEXT:      Value: 0x0
+// CHECK-NEXT:      Size: 0
+// CHECK-NEXT:      Binding: Global (0x1)
+// CHECK-NEXT:      Type: None (0x0)
+// CHECK-NEXT:      Other: 0
+// CHECK-NEXT:      Section: Undefined (0x0)
+// CHECK-NEXT:    }
+// CHECK-NEXT:    Symbol {
+// CHECK-NEXT:      Name: @??_R0?AVinvalid_argument at std@@@8 (1)
+// CHECK-NEXT:      Value: 0x0
+// CHECK-NEXT:      Size: 0
+// CHECK-NEXT:      Binding: Global (0x1)
+// CHECK-NEXT:      Type: None (0x0)
+// CHECK-NEXT:      Other: 0
+// CHECK-NEXT:      Section: Undefined (0x0)
+// CHECK-NEXT:    }
+// CHECK-NEXT:    Symbol {
+// CHECK-NEXT:      Name: __imp_??_R0?AVlogic_error at std@@@8 (35)
+// CHECK-NEXT:      Value: 0x0
+// CHECK-NEXT:      Size: 0
+// CHECK-NEXT:      Binding: Global (0x1)
+// CHECK-NEXT:      Type: None (0x0)
+// CHECK-NEXT:      Other: 0
+// CHECK-NEXT:      Section: Undefined (0x0)
+// CHECK-NEXT:    }
+// CHECK-NEXT:    Symbol {
+// CHECK-NEXT:      Name: __imp_@??_R0PAVexception at std@@@8 (69)
+// CHECK-NEXT:      Value: 0x0
+// CHECK-NEXT:      Size: 0
+// CHECK-NEXT:      Binding: Global (0x1)
+// CHECK-NEXT:      Type: None (0x0)
+// CHECK-NEXT:      Other: 0
+// CHECK-NEXT:      Section: Undefined (0x0)
+// CHECK-NEXT:    }
+// CHECK-NEXT:  ]
--
1.8.4.2

Benoit Belley
Sr Principal Developer
M&E-Product Development Group

MAIN +1 514 393 1616
DIRECT +1 438 448 6304
FAX +1 514 393 0110

Twitter<http://twitter.com/autodesk>
Facebook<https://www.facebook.com/Autodesk>

Autodesk, Inc.
10 Duke Street
Montreal, Quebec, Canada H3C 2L7
www.autodesk.com<http://www.autodesk.com/>

[Description: Email_Signature_Logobar]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141210/5901b7c9/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 350F40DB-4457-4455-A632-0DF05738AF15[6].png
Type: image/png
Size: 4316 bytes
Desc: 350F40DB-4457-4455-A632-0DF05738AF15[6].png
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141210/5901b7c9/attachment.png>


More information about the llvm-dev mailing list