[WebAssembly] Add new explicit relocation types for PIC relocations

See https://github.com/WebAssembly/tool-conventions/pull/106

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

llvm-svn: 357710
diff --git a/llvm/include/llvm/BinaryFormat/WasmRelocs.def b/llvm/include/llvm/BinaryFormat/WasmRelocs.def
index 59a786b..00dacf7 100644
--- a/llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ b/llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -2,14 +2,16 @@
 #error "WASM_RELOC must be defined"
 #endif
 
-WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB,   0)
-WASM_RELOC(R_WASM_TABLE_INDEX_SLEB,     1)
-WASM_RELOC(R_WASM_TABLE_INDEX_I32,      2)
-WASM_RELOC(R_WASM_MEMORY_ADDR_LEB,      3)
-WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB,     4)
-WASM_RELOC(R_WASM_MEMORY_ADDR_I32,      5)
-WASM_RELOC(R_WASM_TYPE_INDEX_LEB,       6)
-WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB,     7)
-WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32,  8)
-WASM_RELOC(R_WASM_SECTION_OFFSET_I32,   9)
-WASM_RELOC(R_WASM_EVENT_INDEX_LEB,     10)
+WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB,    0)
+WASM_RELOC(R_WASM_TABLE_INDEX_SLEB,      1)
+WASM_RELOC(R_WASM_TABLE_INDEX_I32,       2)
+WASM_RELOC(R_WASM_MEMORY_ADDR_LEB,       3)
+WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB,      4)
+WASM_RELOC(R_WASM_MEMORY_ADDR_I32,       5)
+WASM_RELOC(R_WASM_TYPE_INDEX_LEB,        6)
+WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB,      7)
+WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32,   8)
+WASM_RELOC(R_WASM_SECTION_OFFSET_I32,    9)
+WASM_RELOC(R_WASM_EVENT_INDEX_LEB,      10)
+WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
+WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 9465882..7062477 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -284,7 +284,9 @@
     VK_Hexagon_IE,
     VK_Hexagon_IE_GOT,
 
-    VK_WebAssembly_TYPEINDEX,// Reference to a symbol's type (signature)
+    VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
+    VK_WASM_MBREL,     // Memory address relative to memory base
+    VK_WASM_TBREL,     // Table index relative to table bare
 
     VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
     VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 749c323..fe14272 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -302,7 +302,9 @@
   case VK_Hexagon_LD_PLT: return "LDPLT";
   case VK_Hexagon_IE: return "IE";
   case VK_Hexagon_IE_GOT: return "IEGOT";
-  case VK_WebAssembly_TYPEINDEX: return "TYPEINDEX";
+  case VK_WASM_TYPEINDEX: return "TYPEINDEX";
+  case VK_WASM_MBREL: return "MBREL";
+  case VK_WASM_TBREL: return "TBREL";
   case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
   case VK_AMDGPU_GOTPCREL32_HI: return "gotpcrel32@hi";
   case VK_AMDGPU_REL32_LO: return "rel32@lo";
@@ -415,7 +417,9 @@
     .Case("lo8", VK_AVR_LO8)
     .Case("hi8", VK_AVR_HI8)
     .Case("hlo8", VK_AVR_HLO8)
-    .Case("typeindex", VK_WebAssembly_TYPEINDEX)
+    .Case("typeindex", VK_WASM_TYPEINDEX)
+    .Case("tbrel", VK_WASM_TBREL)
+    .Case("mbrel", VK_WASM_MBREL)
     .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
     .Case("gotpcrel32@hi", VK_AMDGPU_GOTPCREL32_HI)
     .Case("rel32@lo", VK_AMDGPU_REL32_LO)
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 4c60952..6367709 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -151,6 +151,7 @@
     switch (Type) {
     case wasm::R_WASM_MEMORY_ADDR_LEB:
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
+    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_I32:
     case wasm::R_WASM_FUNCTION_OFFSET_I32:
     case wasm::R_WASM_SECTION_OFFSET_I32:
@@ -580,6 +581,7 @@
   }
 
   switch (RelEntry.Type) {
+  case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
   case wasm::R_WASM_TABLE_INDEX_SLEB:
   case wasm::R_WASM_TABLE_INDEX_I32: {
     // Provisional value is table address of the resolved symbol itself
@@ -604,6 +606,7 @@
   }
   case wasm::R_WASM_MEMORY_ADDR_LEB:
   case wasm::R_WASM_MEMORY_ADDR_I32:
+  case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
   case wasm::R_WASM_MEMORY_ADDR_SLEB: {
     // Provisional value is address of the global
     const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol);
@@ -698,7 +701,9 @@
       writeI32(Stream, Value, Offset);
       break;
     case wasm::R_WASM_TABLE_INDEX_SLEB:
+    case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
+    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
       writePatchableSLEB(Stream, Value, Offset);
       break;
     default:
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 7a27691..9d52154 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -767,6 +767,7 @@
     case wasm::R_WASM_FUNCTION_INDEX_LEB:
     case wasm::R_WASM_TABLE_INDEX_SLEB:
     case wasm::R_WASM_TABLE_INDEX_I32:
+    case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
       if (!isValidFunctionSymbol(Reloc.Index))
         return make_error<GenericBinaryError>("Bad relocation function index",
                                               object_error::parse_failed);
@@ -793,6 +794,7 @@
     case wasm::R_WASM_MEMORY_ADDR_LEB:
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_I32:
+    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
       if (!isValidDataSymbol(Reloc.Index))
         return make_error<GenericBinaryError>("Bad relocation data index",
                                               object_error::parse_failed);
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 69c477b..4c7114e 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -90,9 +90,21 @@
 enum TOF {
   MO_NO_FLAG = 0,
 
-  // Address of data symbol via a wasm global.  This adds a level of indirection
-  // similar to the GOT on native platforms.
+  // On a symbol operand this indicates that the immediate is a wasm global
+  // index.  The value of the wasm global will be set to the symbol address at
+  // runtime.  This adds a level of indirection similar to the GOT on native
+  // platforms.
   MO_GOT,
+
+  // On a symbol operand this indicates that the immediate is the symbol
+  // address relative the __memory_base wasm global.
+  // Only applicable to data symbols.
+  MO_MEMORY_BASE_REL,
+
+  // On a symbol operand this indicates that the immediate is the symbol
+  // address relative the __table_base wasm global.
+  // Only applicable to function symbols.
+  MO_TABLE_BASE_REL,
 };
 
 } // end namespace WebAssemblyII
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
index 91b356d..a1cc3e2 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -42,14 +42,6 @@
 WebAssemblyWasmObjectWriter::WebAssemblyWasmObjectWriter(bool Is64Bit)
     : MCWasmObjectTargetWriter(Is64Bit) {}
 
-static bool isFunctionSignatureRef(const MCSymbolRefExpr *Ref) {
-  return Ref->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX;
-}
-
-static bool isGOTRef(const MCSymbolRefExpr *Ref) {
-  return Ref->getKind() == MCSymbolRefExpr::VK_GOT;
-}
-
 static const MCSection *getFixupSection(const MCExpr *Expr) {
   if (auto SyExp = dyn_cast<MCSymbolRefExpr>(Expr)) {
     if (SyExp->getSymbol().isInSection())
@@ -75,6 +67,23 @@
   assert(RefA);
   auto& SymA = cast<MCSymbolWasm>(RefA->getSymbol());
 
+  MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
+
+  switch (Modifier) {
+    case MCSymbolRefExpr::VK_GOT:
+      return wasm::R_WASM_GLOBAL_INDEX_LEB;
+    case MCSymbolRefExpr::VK_WASM_TBREL:
+      assert(SymA.isFunction());
+      return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
+    case MCSymbolRefExpr::VK_WASM_MBREL:
+      assert(SymA.isData());
+      return wasm::R_WASM_MEMORY_ADDR_REL_SLEB;
+    case MCSymbolRefExpr::VK_WASM_TYPEINDEX:
+      return wasm::R_WASM_TYPE_INDEX_LEB;
+    default:
+      break;
+  }
+
   switch (unsigned(Fixup.getKind())) {
   case WebAssembly::fixup_sleb128_i32:
     if (SymA.isFunction())
@@ -83,14 +92,10 @@
   case WebAssembly::fixup_sleb128_i64:
     llvm_unreachable("fixup_sleb128_i64 not implemented yet");
   case WebAssembly::fixup_uleb128_i32:
-    if (SymA.isGlobal() || isGOTRef(RefA))
+    if (SymA.isGlobal())
       return wasm::R_WASM_GLOBAL_INDEX_LEB;
-    if (SymA.isFunction()) {
-      if (isFunctionSignatureRef(RefA))
-        return wasm::R_WASM_TYPE_INDEX_LEB;
-      else
-        return wasm::R_WASM_FUNCTION_INDEX_LEB;
-    }
+    if (SymA.isFunction())
+      return wasm::R_WASM_FUNCTION_INDEX_LEB;
     if (SymA.isEvent())
       return wasm::R_WASM_EVENT_INDEX_LEB;
     return wasm::R_WASM_MEMORY_ADDR_LEB;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
index b5e9d9e..7bad497 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -1003,17 +1003,22 @@
       MachineFunction &MF = DAG.getMachineFunction();
       MVT PtrVT = getPointerTy(MF.getDataLayout());
       const char *BaseName;
-      if (GV->getValueType()->isFunctionTy())
+      if (GV->getValueType()->isFunctionTy()) {
         BaseName = MF.createExternalSymbolName("__table_base");
-      else
+        OperandFlags = WebAssemblyII::MO_TABLE_BASE_REL;
+      }
+      else {
         BaseName = MF.createExternalSymbolName("__memory_base");
+        OperandFlags = WebAssemblyII::MO_MEMORY_BASE_REL;
+      }
       SDValue BaseAddr =
           DAG.getNode(WebAssemblyISD::Wrapper, DL, PtrVT,
                       DAG.getTargetExternalSymbol(BaseName, PtrVT));
 
       SDValue SymAddr = DAG.getNode(
           WebAssemblyISD::WrapperPIC, DL, VT,
-          DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset()));
+          DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT, GA->getOffset(),
+                                     OperandFlags));
 
       return DAG.getNode(ISD::ADD, DL, VT, BaseAddr, SymAddr);
     } else {
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index fd09b74..27f13d9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -122,16 +122,31 @@
 
 MCOperand WebAssemblyMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
                                                      MCSymbol *Sym) const {
-  bool isGOT = MO.getTargetFlags() == WebAssemblyII::MO_GOT;
-  MCSymbolRefExpr::VariantKind Kind =
-      isGOT ? MCSymbolRefExpr::VK_GOT : MCSymbolRefExpr::VK_None;
+  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
+  unsigned TargetFlags = MO.getTargetFlags();
+
+  switch (TargetFlags) {
+    case WebAssemblyII::MO_NO_FLAG:
+      break;
+    case WebAssemblyII::MO_GOT:
+      Kind = MCSymbolRefExpr::VK_GOT;
+      break;
+    case WebAssemblyII::MO_MEMORY_BASE_REL:
+      Kind = MCSymbolRefExpr::VK_WASM_MBREL;
+      break;
+    case WebAssemblyII::MO_TABLE_BASE_REL:
+      Kind = MCSymbolRefExpr::VK_WASM_TBREL;
+      break;
+    default:
+      llvm_unreachable("Unknown target flag on GV operand");
+  }
+
   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Kind, Ctx);
 
   if (MO.getOffset() != 0) {
     const auto *WasmSym = cast<MCSymbolWasm>(Sym);
-    if (isGOT)
+    if (TargetFlags == WebAssemblyII::MO_GOT)
       report_fatal_error("GOT symbol references do not support offsets");
-
     if (WasmSym->isFunction())
       report_fatal_error("Function addresses with offsets not supported");
     if (WasmSym->isGlobal())
@@ -217,7 +232,7 @@
           WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
 
           const MCExpr *Expr = MCSymbolRefExpr::create(
-              WasmSym, MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX, Ctx);
+              WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx);
           MCOp = MCOperand::createExpr(Expr);
           break;
         }
diff --git a/llvm/test/CodeGen/WebAssembly/call-pic.ll b/llvm/test/CodeGen/WebAssembly/call-pic.ll
index 7fd93c6..b50f96d 100644
--- a/llvm/test/CodeGen/WebAssembly/call-pic.ll
+++ b/llvm/test/CodeGen/WebAssembly/call-pic.ll
@@ -5,14 +5,14 @@
 
 declare i32 @foo()
 declare i32 @bar()
-declare hidden i32 @hidden_function();
+declare hidden i32 @hidden_function()
 
 @indirect_func = global i32 ()* @foo
 
 define void @call_indirect_func() {
 ; CHECK-LABEL: call_indirect_func:
 ; CHECK:      global.get $push[[L0:[0-9]+]]=, __memory_base{{$}}
-; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, indirect_func{{$}}
+; CHECK-NEXT: i32.const $push[[L1:[0-9]+]]=, indirect_func@MBREL{{$}}
 ; CHECK-NEXT: i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; CHECK-NEXT: i32.load $push[[L3:[0-9]+]]=, 0($pop[[L2]]){{$}}
 ; CHECK-NEXT: i32.call_indirect $push[[L4:[0-9]+]]=, $pop[[L3]]{{$}}
@@ -43,7 +43,7 @@
 define i8* @get_function_address_hidden() {
 ; CHECK-LABEL: get_function_address_hidden:
 ; CHECK:       global.get $push[[L0:[0-9]+]]=, __table_base{{$}}
-; CHECK-NEXT:  i32.const $push[[L1:[0-9]+]]=, hidden_function{{$}}
+; CHECK-NEXT:  i32.const $push[[L1:[0-9]+]]=, hidden_function@TBREL{{$}}
 ; CHECK-NEXT:  i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; CHECK-NEXT:  return $pop[[L2]]{{$}}
 ; CHECK-NEXT:  end_function{{$}}
diff --git a/llvm/test/CodeGen/WebAssembly/load-store-pic.ll b/llvm/test/CodeGen/WebAssembly/load-store-pic.ll
index bb449ca..2f7f34d 100644
--- a/llvm/test/CodeGen/WebAssembly/load-store-pic.ll
+++ b/llvm/test/CodeGen/WebAssembly/load-store-pic.ll
@@ -21,7 +21,7 @@
 define i32 @load_hidden_global() {
 ; CHECK-LABEL: load_hidden_global:
 ; PIC:         global.get $push[[L0:[0-9]+]]=, __memory_base{{$}}
-; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global{{$}}
+; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global@MBREL{{$}}
 ; PIC-NEXT:    i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; PIC-NEXT:    i32.load $push[[L3:[0-9]+]]=, 0($pop[[L2]]){{$}}
 
@@ -36,7 +36,7 @@
 define i32 @load_hidden_global_offset() {
 ; CHECK-LABEL: load_hidden_global_offset:
 ; PIC:         global.get $push[[L0:[0-9]+]]=, __memory_base{{$}}
-; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global_array{{$}}
+; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global_array@MBREL{{$}}
 ; PIC-NEXT:    i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1:[0-9]+]]{{$}}
 ; PIC-NEXT:    i32.const $push[[L3:[0-9]+]]=, 20{{$}}
 ; PIC-NEXT:    i32.add $push[[L4:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
@@ -56,7 +56,7 @@
 define void @store_hidden_global(i32 %n) {
 ; CHECK-LABEL: store_hidden_global:
 ; PIC:         global.get $push[[L0:[0-9]+]]=, __memory_base{{$}}
-; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global{{$}}
+; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global@MBREL{{$}}
 ; PIC-NEXT:    i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; PIC-NEXT:    i32.store 0($pop[[L2]]), $0{{$}}
 
@@ -71,7 +71,7 @@
 define void @store_hidden_global_offset(i32 %n) {
 ; CHECK-LABEL: store_hidden_global_offset:
 ; PIC:         global.get $push[[L0:[0-9]+]]=, __memory_base{{$}}
-; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global_array{{$}}
+; PIC-NEXT:    i32.const $push[[L1:[0-9]+]]=, hidden_global_array@MBREL{{$}}
 ; PIC-NEXT:    i32.add $push[[L2:[0-9]+]]=, $pop[[L0]], $pop[[L1]]{{$}}
 ; PIC-NEXT:    i32.const $push[[L3:[0-9]+]]=, 20{{$}}
 ; PIC-NEXT:    i32.add $push[[L4:[0-9]+]]=, $pop[[L2]], $pop[[L3]]{{$}}
diff --git a/llvm/test/MC/WebAssembly/reloc-pic.s b/llvm/test/MC/WebAssembly/reloc-pic.s
index 49aaa85..249cd1f 100644
--- a/llvm/test/MC/WebAssembly/reloc-pic.s
+++ b/llvm/test/MC/WebAssembly/reloc-pic.s
@@ -16,6 +16,32 @@
     i32.load    0
     end_function
 
+load_hidden_data:
+    .functype   load_hidden_data () -> (i32)
+    global.get  __memory_base
+    i32.const   .L.hidden_data@MBREL
+    i32.add
+    end_function
+
+load_hidden_func:
+    .functype   load_hidden_func () -> (i32)
+    global.get  __table_base
+    i32.const   hidden_func@TBREL
+    i32.add
+    end_function
+
+hidden_func:
+    .functype   hidden_func () -> (i32)
+    i32.const 0
+    end_function
+
+.section .rodata.hidden_data,"",@
+.L.hidden_data:
+    .int8 100
+    .size .L.hidden_data, 1
+
+#.hidden hidden_func
+#.hidden hidden_data
 .size default_data, 4
 .functype default_func () -> (i32)
 
@@ -34,7 +60,7 @@
 # CHECK-NEXT:         Field:           __linear_memory
 # CHECK-NEXT:         Kind:            MEMORY
 # CHECK-NEXT:         Memory:
-# CHECK-NEXT:           Initial:         0x00000000
+# CHECK-NEXT:           Initial:         0x00000001
 # CHECK-NEXT:       - Module:          env
 # CHECK-NEXT:         Field:           __indirect_function_table
 # CHECK-NEXT:         Kind:            TABLE
@@ -57,7 +83,7 @@
 # CHECK-NEXT:         GlobalType:      I32
 # CHECK-NEXT:         GlobalMutable:   true
 # CHECK-NEXT:   - Type:            FUNCTION
-# CHECK-NEXT:     FunctionTypes:   [ 0, 0 ]
+# CHECK-NEXT:     FunctionTypes:   [ 0, 0, 0, 0, 0 ]
 # CHECK-NEXT:   - Type:            CODE
 # CHECK-NEXT:     Relocations:
 # CHECK-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
@@ -66,6 +92,18 @@
 # CHECK-NEXT:       - Type:            R_WASM_GLOBAL_INDEX_LEB
 # CHECK-NEXT:         Index:           3
 # CHECK-NEXT:         Offset:          0x00000010
+# CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
+# CHECK-NEXT:         Index:           5
+# CHECK-NEXT:         Offset:          0x0000001C
+# CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_REL_SLEB
+# CHECK-NEXT:         Index:           6
+# CHECK-NEXT:         Offset:          0x00000022
+# CHECK-NEXT:       - Type:            R_WASM_MEMORY_ADDR_LEB
+# CHECK-NEXT:         Index:           8
+# CHECK-NEXT:         Offset:          0x0000002C
+# CHECK-NEXT:       - Type:            R_WASM_TABLE_INDEX_REL_SLEB
+# CHECK-NEXT:         Index:           9
+# CHECK-NEXT:         Offset:          0x00000032
 # CHECK-NEXT:     Functions:
 # CHECK-NEXT:       - Index:           1
 # CHECK-NEXT:         Locals:          []
@@ -73,6 +111,23 @@
 # CHECK-NEXT:       - Index:           2
 # CHECK-NEXT:         Locals:          []
 # CHECK-NEXT:         Body:            2381808080002800000B
+# CHECK-NEXT:       - Index:           3
+# CHECK-NEXT:         Locals:          []
+# CHECK-NEXT:         Body:            2380808080004180808080006A0B
+# CHECK-NEXT:       - Index:           4
+# CHECK-NEXT:         Locals:          []
+# CHECK-NEXT:         Body:            2380808080004180808080006A0B
+# CHECK-NEXT:       - Index:           5
+# CHECK-NEXT:         Locals:          []
+# CHECK-NEXT:         Body:            41000B
+# CHECK-NEXT:   - Type:            DATA
+# CHECK-NEXT:     Segments:
+# CHECK-NEXT:       - SectionOffset:   6
+# CHECK-NEXT:         InitFlags:       0
+# CHECK-NEXT:         Offset:
+# CHECK-NEXT:           Opcode:          I32_CONST
+# CHECK-NEXT:           Value:           0
+# CHECK-NEXT:         Content:         '64'
 # CHECK-NEXT:   - Type:            CUSTOM
 # CHECK-NEXT:     Name:            linking
 # CHECK-NEXT:     Version:         2
@@ -96,4 +151,38 @@
 # CHECK-NEXT:         Name:            default_func
 # CHECK-NEXT:         Flags:           [ UNDEFINED ]
 # CHECK-NEXT:         Function:        0
+# CHECK-NEXT:       - Index:           4
+# CHECK-NEXT:         Kind:            FUNCTION
+# CHECK-NEXT:         Name:            load_hidden_data
+# CHECK-NEXT:         Flags:           [ BINDING_LOCAL ]
+# CHECK-NEXT:         Function:        3
+# CHECK-NEXT:       - Index:           5
+# CHECK-NEXT:         Kind:            DATA
+# CHECK-NEXT:         Name:            __memory_base
+# CHECK-NEXT:         Flags:           [ UNDEFINED ]
+# CHECK-NEXT:       - Index:           6
+# CHECK-NEXT:         Kind:            DATA
+# CHECK-NEXT:         Name:            .L.hidden_data
+# CHECK-NEXT:         Flags:           [ BINDING_LOCAL ]
+# CHECK-NEXT:         Segment:         0
+# CHECK-NEXT:         Size:            1
+# CHECK-NEXT:       - Index:           7
+# CHECK-NEXT:         Kind:            FUNCTION
+# CHECK-NEXT:         Name:            load_hidden_func
+# CHECK-NEXT:         Flags:           [ BINDING_LOCAL ]
+# CHECK-NEXT:         Function:        4
+# CHECK-NEXT:       - Index:           8
+# CHECK-NEXT:         Kind:            DATA
+# CHECK-NEXT:         Name:            __table_base
+# CHECK-NEXT:         Flags:           [ UNDEFINED ]
+# CHECK-NEXT:       - Index:           9
+# CHECK-NEXT:         Kind:            FUNCTION
+# CHECK-NEXT:         Name:            hidden_func
+# CHECK-NEXT:         Flags:           [ BINDING_LOCAL ]
+# CHECK-NEXT:         Function:        5
+# CHECK-NEXT:     SegmentInfo:
+# CHECK-NEXT:       - Index:           0
+# CHECK-NEXT:         Name:            .rodata.hidden_data
+# CHECK-NEXT:         Alignment:       0
+# CHECK-NEXT:         Flags:           [  ]
 # CHECK-NEXT: ...