]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Fix symbol type for addresses of external functions
authorSam Clegg <sbc@chromium.org>
Tue, 13 Jun 2017 01:42:21 +0000 (01:42 +0000)
committerSam Clegg <sbc@chromium.org>
Tue, 13 Jun 2017 01:42:21 +0000 (01:42 +0000)
These symbols were previously not being marked as functions
so were appearing as globals instead, and with the incorrect
relocation type.

Without this fix, objects that take address of external
functions include them as global imports rather than function
imports which then fails at link time.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305263 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
test/MC/WebAssembly/external-data.ll
test/MC/WebAssembly/external-func-address.ll [new file with mode: 0644]

index 4178ec0b28f052b74a7fbafc8e3636fe445281a7..b999091e2d2940476b2e0a28a86a0cce6ed61b3a 100644 (file)
@@ -33,6 +33,8 @@
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolWasm.h"
+#include "llvm/MC/MCSymbolELF.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
@@ -218,9 +220,13 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
 const MCExpr *WebAssemblyAsmPrinter::lowerConstant(const Constant *CV) {
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
-    if (GV->getValueType()->isFunctionTy())
+    if (GV->getValueType()->isFunctionTy()) {
+      MCSymbol* Sym = getSymbol(GV);
+      if (!isa<MCSymbolELF>(Sym))
+        cast<MCSymbolWasm>(Sym)->setIsFunction(true);
       return MCSymbolRefExpr::create(
-          getSymbol(GV), MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
+          Sym, MCSymbolRefExpr::VK_WebAssembly_FUNCTION, OutContext);
+    }
   return AsmPrinter::lowerConstant(CV);
 }
 
index 91e05b3f13a612fd92595d79092efd4f0e1ea118..6914736ac671ae34365f040557a76e76e5f32591 100644 (file)
@@ -2,10 +2,10 @@
 ; Verify relocations are correctly generated for addresses of externals
 ; in the data section.
 
-declare i32 @f1(...)
+@myimport = external global i32, align 4
 
 @foo = global i64 7, align 4
-@far = local_unnamed_addr global i32 (...)* @f1, align 4
+@bar = hidden global i32* @myimport, align 4
 
 ; CHECK:   - Type:            DATA
 ; CHECK:     Relocations:
diff --git a/test/MC/WebAssembly/external-func-address.ll b/test/MC/WebAssembly/external-func-address.ll
new file mode 100644 (file)
index 0000000..4022b2c
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s
+; Verify that addresses of external functions generate correctly typed
+; imports and relocations or type R_TABLE_INDEX_I32.
+
+declare void @f1() #1
+@ptr_to_f1 = hidden global void ()* @f1, align 4
+
+
+; CHECK:   - Type:            IMPORT
+; CHECK:     Imports:
+; CHECK:       - Module:          env
+; CHECK:         Field:           f1
+; CHECK:         Kind:            FUNCTION
+; CHECK:         SigIndex:        0
+; CHECK:   - Type:            ELEM
+; CHECK:     Segments:
+; CHECK:       - Offset:
+; CHECK:           Opcode:          I32_CONST
+; CHECK:           Value:           0
+; CHECK:         Functions:       [ 0 ]
+; CHECK:   - Type:            DATA
+; CHECK:     Relocations:
+; CHECK:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK:         Index:           0
+; CHECK:         Offset:          0x00000006