[llvm] f7d2afb - [CodeGen] Emit COFF symbol type for function aliases

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 28 03:06:44 PST 2022


Author: Martin Storsjö
Date: 2022-01-28T13:06:16+02:00
New Revision: f7d2afbac904d3605b984b5b34cfd3aec8616e63

URL: https://github.com/llvm/llvm-project/commit/f7d2afbac904d3605b984b5b34cfd3aec8616e63
DIFF: https://github.com/llvm/llvm-project/commit/f7d2afbac904d3605b984b5b34cfd3aec8616e63.diff

LOG: [CodeGen] Emit COFF symbol type for function aliases

On the level of the generated object files, both symbols (both
original and alias) are generally indistinguishable - both are
regular defined symbols. But previously, only the original
function had the COFF ComplexType set to IMAGE_SYM_DTYPE_FUNCTION,
while the symbol created via an alias had the type set to
IMAGE_SYM_DTYPE_NULL.

This matches what GCC does, which emits directives for setting the
COFF symbol type for this kind of alias symbol too.

This makes a difference when GNU ld.bfd exports symbols without
dllexport directives or a def file - it seems to decide between
function or data exports based on the COFF symbol type. This means
that functions created via aliases, like some C++ constructors,
are exported as data symbols (missing the thunk for calling without
dllimport).

The hasnt been an issue when doing the same with LLD, as LLD decides
between function or data export based on the flags of the section
that the symbol points at.

This should fix the root cause of
https://github.com/msys2/MINGW-packages/issues/10547.

Differential Revision: https://reviews.llvm.org/D118328

Added: 
    llvm/test/CodeGen/X86/coff-alias-type.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 4f3f798fe6f80..3e8e190eecc3f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1647,8 +1647,18 @@ void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
 
   // Set the symbol type to function if the alias has a function type.
   // This affects codegen when the aliasee is not a function.
-  if (IsFunction)
+  if (IsFunction) {
     OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
+    if (TM.getTargetTriple().isOSBinFormatCOFF()) {
+      OutStreamer->BeginCOFFSymbolDef(Name);
+      OutStreamer->EmitCOFFSymbolStorageClass(
+          GA.hasLocalLinkage() ? COFF::IMAGE_SYM_CLASS_STATIC
+                               : COFF::IMAGE_SYM_CLASS_EXTERNAL);
+      OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
+                                      << COFF::SCT_COMPLEX_TYPE_SHIFT);
+      OutStreamer->EndCOFFSymbolDef();
+    }
+  }
 
   emitVisibility(Name, GA.getVisibility());
 

diff  --git a/llvm/test/CodeGen/X86/coff-alias-type.ll b/llvm/test/CodeGen/X86/coff-alias-type.ll
new file mode 100644
index 0000000000000..56c1cc68b2505
--- /dev/null
+++ b/llvm/test/CodeGen/X86/coff-alias-type.ll
@@ -0,0 +1,24 @@
+; RUN: llc -mtriple=x86_64-windows-gnu -o - %s | FileCheck %s
+
+%struct.MyStruct = type { i8 }
+
+ at _ZN8MyStructC1Ev = dso_local alias void (%struct.MyStruct*), void (%struct.MyStruct*)* @_ZN8MyStructC2Ev
+
+define dso_local void @_ZN8MyStructC2Ev(%struct.MyStruct* %this) {
+entry:
+  ret void
+}
+
+; CHECK:      .def     _ZN8MyStructC2Ev
+; CHECK-NEXT: .scl     2
+; CHECK-NEXT: .type    32
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .globl   _ZN8MyStructC2Ev
+; CHECK:      {{^}}_ZN8MyStructC2Ev:
+
+; CHECK:      .globl   _ZN8MyStructC1Ev
+; CHECK-NEXT: .def     _ZN8MyStructC1Ev
+; CHECK-NEXT: .scl     2
+; CHECK-NEXT: .type    32
+; CHECK-NEXT: .endef
+; CHECK-NEXT: .set     _ZN8MyStructC1Ev, _ZN8MyStructC2Ev


        


More information about the llvm-commits mailing list