[JITLink][COFF] Implement IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY/LIBRARY.
authorSunho Kim <ksunhokim123@gmail.com>
Tue, 26 Jul 2022 03:46:34 +0000 (12:46 +0900)
committerSunho Kim <ksunhokim123@gmail.com>
Tue, 26 Jul 2022 03:46:34 +0000 (12:46 +0900)
Implement IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY/LIBRARY characteristics flag.

Since COFFObjectFile class will set undefined flag for symbols with no alias flag, ORC ObjectFileInterface will not pull in this symbol. So, we only need to make sure the scope is local. NOLIBRARY and LIBRARY are handled in the same way for now. (which is what lld does right now)

Reviewed By: lhames

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

llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
llvm/test/ExecutionEngine/JITLink/X86/COFF_nolibrary_search.s [new file with mode: 0644]
llvm/test/ExecutionEngine/JITLink/X86/Inputs/COFF_weak_nolibrary_serach_def.yaml [new file with mode: 0644]

index dcaefd7..365da3b 100644 (file)
@@ -236,15 +236,11 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
             &G->addExternalSymbol(SymbolName, Sym->getValue(), Linkage::Strong);
       GSym = ExternalSymbols[SymbolName];
     } else if (Sym->isWeakExternal()) {
-      COFFSymbolIndex TagIndex =
-          Sym->getAux<object::coff_aux_weak_external>()->TagIndex;
-      assert(Sym->getAux<object::coff_aux_weak_external>()->Characteristics !=
-                 COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY &&
-             "IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY is not supported.");
-      assert(Sym->getAux<object::coff_aux_weak_external>()->Characteristics !=
-                 COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY &&
-             "IMAGE_WEAK_EXTERN_SEARCH_LIBRARY is not supported.");
-      WeakAliasRequests.push_back({SymIndex, TagIndex, SymbolName});
+      auto *WeakExternal = Sym->getAux<object::coff_aux_weak_external>();
+      COFFSymbolIndex TagIndex = WeakExternal->TagIndex;
+      uint32_t Characteristics = WeakExternal->Characteristics;
+      WeakExternalRequests.push_back(
+          {SymIndex, TagIndex, Characteristics, SymbolName});
     } else {
       Expected<jitlink::Symbol *> NewGSym =
           createDefinedSymbol(SymIndex, SymbolName, *Sym, Sec);
@@ -280,35 +276,41 @@ Error COFFLinkGraphBuilder::graphifySymbols() {
 
 Error COFFLinkGraphBuilder::flushWeakAliasRequests() {
   // Export the weak external symbols and alias it
-  for (auto &WeakAlias : WeakAliasRequests) {
-    if (auto *Target = getGraphSymbol(WeakAlias.Target)) {
+  for (auto &WeakExternal : WeakExternalRequests) {
+    if (auto *Target = getGraphSymbol(WeakExternal.Target)) {
       Expected<object::COFFSymbolRef> AliasSymbol =
-          Obj.getSymbol(WeakAlias.Alias);
+          Obj.getSymbol(WeakExternal.Alias);
       if (!AliasSymbol)
         return AliasSymbol.takeError();
 
+      // FIXME: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY and
+      // IMAGE_WEAK_EXTERN_SEARCH_LIBRARY are handled in the same way.
+      Scope S =
+          WeakExternal.Characteristics == COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS
+              ? Scope::Default
+              : Scope::Local;
+
       // FIXME: Support this when there's a way to handle this.
       if (!Target->isDefined())
         return make_error<JITLinkError>("Weak external symbol with external "
                                         "symbol as alternative not supported.");
 
       jitlink::Symbol *NewSymbol = &G->addDefinedSymbol(
-          Target->getBlock(), Target->getOffset(), WeakAlias.SymbolName,
-          Target->getSize(), Linkage::Weak, Scope::Default,
-          Target->isCallable(), false);
-      setGraphSymbol(AliasSymbol->getSectionNumber(), WeakAlias.Alias,
+          Target->getBlock(), Target->getOffset(), WeakExternal.SymbolName,
+          Target->getSize(), Linkage::Weak, S, Target->isCallable(), false);
+      setGraphSymbol(AliasSymbol->getSectionNumber(), WeakExternal.Alias,
                      *NewSymbol);
       LLVM_DEBUG({
-        dbgs() << "    " << WeakAlias.Alias
+        dbgs() << "    " << WeakExternal.Alias
                << ": Creating weak external symbol for COFF symbol \""
-               << WeakAlias.SymbolName << "\" in section "
+               << WeakExternal.SymbolName << "\" in section "
                << AliasSymbol->getSectionNumber() << "\n";
         dbgs() << "      " << *NewSymbol << "\n";
       });
     } else
       return make_error<JITLinkError>("Weak symbol alias requested but actual "
                                       "symbol not found for symbol " +
-                                      formatv("{0:d}", WeakAlias.Alias));
+                                      formatv("{0:d}", WeakExternal.Alias));
   }
   return Error::success();
 }
index 26cb857..f925f6d 100644 (file)
@@ -117,12 +117,13 @@ private:
 
   // This represents a pending request to create a weak external symbol with a
   // name.
-  struct WeakAliasRequest {
+  struct WeakExternalRequest {
     COFFSymbolIndex Alias;
     COFFSymbolIndex Target;
+    uint32_t Characteristics;
     StringRef SymbolName;
   };
-  std::vector<WeakAliasRequest> WeakAliasRequests;
+  std::vector<WeakExternalRequest> WeakExternalRequests;
 
   // Per COFF section jitlink symbol set sorted by offset.
   // Used for calculating implicit size of defined symbols.
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/COFF_nolibrary_search.s b/llvm/test/ExecutionEngine/JITLink/X86/COFF_nolibrary_search.s
new file mode 100644 (file)
index 0000000..d3d94ed
--- /dev/null
@@ -0,0 +1,23 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: yaml2obj %S/Inputs/COFF_weak_nolibrary_serach_def.yaml -o %t/COFF_weak.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc %s -o %t/COFF_main.o
+# RUN: not llvm-jitlink -noexec -abs __ImageBase=0xfff00000 \
+# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
+# RUN: %t/COFF_weak.o %t/COFF_main.o 2>&1 | FileCheck %s
+#
+# Check weak external symbol with IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY Characteristics
+# does not export symbol.
+#
+# CHECK: llvm-jitlink error: Symbols not found: [ func ]
+
+       .text
+
+       .def    main;
+       .scl    2;
+       .type   32;
+       .endef
+       .globl  main
+       .p2align        4, 0x90
+main:
+    callq func
+       retq
\ No newline at end of file
diff --git a/llvm/test/ExecutionEngine/JITLink/X86/Inputs/COFF_weak_nolibrary_serach_def.yaml b/llvm/test/ExecutionEngine/JITLink/X86/Inputs/COFF_weak_nolibrary_serach_def.yaml
new file mode 100644 (file)
index 0000000..55c9956
--- /dev/null
@@ -0,0 +1,80 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     C3662E0F1F8400000000000F1F440000E800000000C3
+    Relocations:
+      - VirtualAddress:  17
+        SymbolName:      func
+        Type:            IMAGE_REL_AMD64_REL32
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .bss
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+    SizeOfRawData:   0
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          22
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        1179995423
+      Number:          1
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
+  - Name:            .bss
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            func
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_WEAK_EXTERNAL
+    WeakExternal:
+      TagIndex:        8
+      Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
+  - Name:            .weak.func.default.main
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            using_func
+    Value:           16
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL