]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Add new explicit relocation types for PIC relocations
authorSam Clegg <sbc@chromium.org>
Thu, 4 Apr 2019 17:43:50 +0000 (17:43 +0000)
committerSam Clegg <sbc@chromium.org>
Thu, 4 Apr 2019 17:43:50 +0000 (17:43 +0000)
See https://github.com/WebAssembly/tool-conventions/pull/106

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

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

12 files changed:
include/llvm/BinaryFormat/WasmRelocs.def
include/llvm/MC/MCExpr.h
lib/MC/MCExpr.cpp
lib/MC/WasmObjectWriter.cpp
lib/Object/WasmObjectFile.cpp
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
test/CodeGen/WebAssembly/call-pic.ll
test/CodeGen/WebAssembly/load-store-pic.ll
test/MC/WebAssembly/reloc-pic.s

index 59a786bb8fb9a515d681e10d6fdfb6dd2c066660..00dacf72abb0a8901bffd2b447ea65553ca6eb7a 100644 (file)
@@ -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)
index 94658822edca926e999c2b73c779b607f99f39ae..706247746fba5f3bd3612fe4d729544d4f2fd5c2 100644 (file)
@@ -284,7 +284,9 @@ public:
     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
index 749c3232cfcb5a3ca63aa65307d39b8b8f0d4f92..fe14272a189b63ef0f0a73c30ff14712ef9220e4 100644 (file)
@@ -302,7 +302,9 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   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 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
     .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)
index 4c6095262372d3814e9c4a59658198ed466e3721..636770959182755eee69e7767e5cb8cc4210521f 100644 (file)
@@ -151,6 +151,7 @@ struct WasmRelocationEntry {
     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 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
   }
 
   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 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
   }
   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 @@ void WasmObjectWriter::applyRelocations(
       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:
index 7a2769149add511f3393c06a20984efed55bca95..9d521544593afa2dec56b36a6bb93e4a7d836959 100644 (file)
@@ -767,6 +767,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
     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 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
     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);
index 69c477bbbb5785f0c1505677f23cf975eac54978..4c7114eea11da719085af82fe6271a7ededc54c6 100644 (file)
@@ -90,9 +90,21 @@ namespace WebAssemblyII {
 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
index 91b356db81d91f970b41c38ca9ae2ea2f10efc24..a1cc3e268e8f764b1cb570993d7b01b307aa9be2 100644 (file)
@@ -42,14 +42,6 @@ private:
 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 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
   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 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
   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;
index b5e9d9e9723f1a1ff4c38598f79e3d6c321262e2..7bad4972c4fe3bdbf3d05b71e1a303e296755957 100644 (file)
@@ -1003,17 +1003,22 @@ SDValue WebAssemblyTargetLowering::LowerGlobalAddress(SDValue Op,
       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 {
index fd09b749c73f3f7a6f5f3c881f8bf6abb74b2f7f..27f13d9639a06910cc86e3627bb7e51af17a4676 100644 (file)
@@ -122,16 +122,31 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
 
 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 @@ void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
           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;
         }
index 7fd93c65b772315f100ff8da379ea4cc71add838..b50f96d6d7239d75c9d70612b8bb7af2b1334540 100644 (file)
@@ -5,14 +5,14 @@ target triple = "wasm32-unknown-unknown"
 
 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() {
 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{{$}}
index bb449cadca8a14f8a67beffb8498cc9d7abae6ae..2f7f34ddf6fe795f847d58c5c23f894514ab4525 100644 (file)
@@ -21,7 +21,7 @@ declare i32 @foo();
 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() {
 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 i32 @load_hidden_global_offset() {
 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(i32 %n) {
 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]]{{$}}
index 49aaa858aec33a40d94ed239667fae93e1b19116..249cd1fb89a4f27a15c77dd591d47c7df6b67342 100644 (file)
@@ -16,6 +16,32 @@ load_default_func:
     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 @@ load_default_func:
 # 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 @@ load_default_func:
 # 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 @@ load_default_func:
 # 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 @@ load_default_func:
 # 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 @@ load_default_func:
 # 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: ...