]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] MC: Refactor relocation handling
authorSam Clegg <sbc@chromium.org>
Tue, 6 Jun 2017 19:15:05 +0000 (19:15 +0000)
committerSam Clegg <sbc@chromium.org>
Tue, 6 Jun 2017 19:15:05 +0000 (19:15 +0000)
The change cleans up and unifies the handling of relocation
entries in WasmObjectWriter.  Type index relocation no longer
need to be handled separately.

The only externally visible change should be that type
index relocations are no longer grouped at the end.

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

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

include/llvm/MC/MCWasmObjectWriter.h
lib/MC/WasmObjectWriter.cpp
lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
test/MC/WebAssembly/reloc-code.ll

index 25d8c1486d8de6a54aa2cc52dbcb2f1e1e40e648..004e4b781657814c78d8b547793e3b941ec3840a 100644 (file)
@@ -14,6 +14,7 @@
 #include "llvm/MC/MCValue.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Wasm.h"
 #include <vector>
 
 namespace llvm {
index ee5957a8079e44f8ba29ec7ca564ed418d6a51a4..5f36a9ecce9121d7d8a068650fbb2a5a72e81549 100644 (file)
@@ -31,7 +31,6 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/LEB128.h"
 #include "llvm/Support/StringSaver.h"
-#include "llvm/Support/Wasm.h"
 #include <vector>
 
 using namespace llvm;
@@ -141,6 +140,17 @@ struct WasmRelocationEntry {
       : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type),
         FixupSection(FixupSection) {}
 
+  bool hasAddend() const {
+    switch (Type) {
+    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
+    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
+    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
+      return true;
+    default:
+      return false;
+    }
+  }
+
   void print(raw_ostream &Out) const {
     Out << "Off=" << Offset << ", Sym=" << Symbol << ", Addend=" << Addend
         << ", Type=" << Type << ", FixupSection=" << FixupSection;
@@ -167,11 +177,14 @@ class WasmObjectWriter : public MCObjectWriter {
   // Relocations for fixing up references in the data section.
   std::vector<WasmRelocationEntry> DataRelocations;
 
-  // Fixups for call_indirect type indices.
-  std::vector<WasmRelocationEntry> TypeIndexFixups;
-
   // Index values to use for fixing up call_indirect type indices.
-  std::vector<uint32_t> TypeIndexFixupTypes;
+  // Maps function symbols to the index of the type of the function
+  DenseMap<const MCSymbolWasm *, uint32_t> TypeIndices;
+
+  DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
+
+  DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
+      FunctionTypeIndices;
 
   // TargetObjectWriter wrappers.
   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
@@ -191,6 +204,15 @@ public:
 private:
   ~WasmObjectWriter() override;
 
+  void reset() override {
+    CodeRelocations.clear();
+    DataRelocations.clear();
+    TypeIndices.clear();
+    SymbolIndices.clear();
+    FunctionTypeIndices.clear();
+    MCObjectWriter::reset();
+  }
+
   void writeHeader(const MCAssembler &Asm);
 
   void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
@@ -216,21 +238,23 @@ private:
   void writeExportSection(const SmallVector<WasmExport, 4> &Exports);
   void writeElemSection(const SmallVector<uint32_t, 4> &TableElems);
   void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
-                        DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
                         const SmallVector<WasmFunction, 4> &Functions);
   uint64_t
-  writeDataSection(const SmallVector<char, 0> &DataBytes,
-                   DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices);
+  writeDataSection(const SmallVector<char, 0> &DataBytes);
   void writeNameSection(const SmallVector<WasmFunction, 4> &Functions,
                         const SmallVector<WasmImport, 4> &Imports,
                         uint32_t NumFuncImports);
-  void writeCodeRelocSection(
-      DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices);
-  void writeDataRelocSection(
-      DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
-      uint64_t DataSectionHeaderSize);
+  void writeCodeRelocSection();
+  void writeDataRelocSection(uint64_t DataSectionHeaderSize);
   void writeLinkingMetaDataSection(bool HasStackPointer,
                                    uint32_t StackPointerGlobal);
+
+  void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
+                        uint64_t ContentsOffset);
+
+  void writeRelocations(ArrayRef<WasmRelocationEntry> Relocations,
+                        uint64_t HeaderSize);
+  uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
 };
 
 } // end anonymous namespace
@@ -377,19 +401,7 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
       SymA->setUsedInReloc();
   }
 
-  if (RefA) {
-    if (RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX) {
-      assert(C == 0);
-      WasmRelocationEntry Rec(FixupOffset, SymA, C,
-                              wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB,
-                              &FixupSection);
-      TypeIndexFixups.push_back(Rec);
-      return;
-    }
-  }
-
   unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel);
-
   WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
 
   if (FixupSection.hasInstructions())
@@ -448,124 +460,85 @@ static uint32_t ProvisionalValue(const WasmRelocationEntry &RelEntry) {
   return Value;
 }
 
+uint32_t WasmObjectWriter::getRelocationIndexValue(
+    const WasmRelocationEntry &RelEntry) {
+  switch (RelEntry.Type) {
+  case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+  case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+  case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
+  case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
+  case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
+  case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
+    assert(SymbolIndices.count(RelEntry.Symbol));
+    return SymbolIndices[RelEntry.Symbol];
+  case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
+    assert(TypeIndices.count(RelEntry.Symbol));
+    return TypeIndices[RelEntry.Symbol];
+  default:
+    llvm_unreachable("invalid relocation type");
+  }
+}
+
 // Apply the portions of the relocation records that we can handle ourselves
 // directly.
-static void ApplyRelocations(
-    ArrayRef<WasmRelocationEntry> Relocations,
-    raw_pwrite_stream &Stream,
-    DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
-    uint64_t ContentsOffset)
-{
+void WasmObjectWriter::applyRelocations(
+    ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset) {
+  raw_pwrite_stream &Stream = getStream();
   for (const WasmRelocationEntry &RelEntry : Relocations) {
     uint64_t Offset = ContentsOffset +
                       RelEntry.FixupSection->getSectionOffset() +
                       RelEntry.Offset;
-    switch (RelEntry.Type) {
-    case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: {
-      assert(SymbolIndices.count(RelEntry.Symbol));
-      uint32_t Index = SymbolIndices[RelEntry.Symbol];
-      assert(RelEntry.Addend == 0);
 
-      WritePatchableLEB(Stream, Index, Offset);
+    switch (RelEntry.Type) {
+    case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+    case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
+    case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: {
+      uint32_t Index = getRelocationIndexValue(RelEntry);
+      WritePatchableSLEB(Stream, Index, Offset);
       break;
     }
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
-      assert(SymbolIndices.count(RelEntry.Symbol));
-      uint32_t Index = SymbolIndices[RelEntry.Symbol];
-      assert(RelEntry.Addend == 0);
-
-      WritePatchableSLEB(Stream, Index, Offset);
+    case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
+      uint32_t Index = getRelocationIndexValue(RelEntry);
+      WriteI32(Stream, Index, Offset);
       break;
     }
     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB: {
       uint32_t Value = ProvisionalValue(RelEntry);
-
       WritePatchableSLEB(Stream, Value, Offset);
       break;
     }
     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB: {
       uint32_t Value = ProvisionalValue(RelEntry);
-
       WritePatchableLEB(Stream, Value, Offset);
       break;
     }
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
-      assert(SymbolIndices.count(RelEntry.Symbol));
-      uint32_t Index = SymbolIndices[RelEntry.Symbol];
-      assert(RelEntry.Addend == 0);
-
-      WriteI32(Stream, Index, Offset);
-      break;
-    }
     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32: {
       uint32_t Value = ProvisionalValue(RelEntry);
-
       WriteI32(Stream, Value, Offset);
       break;
     }
     default:
-      break;
+      llvm_unreachable("unsupported relocation type");
     }
   }
 }
 
 // Write out the portions of the relocation records that the linker will
 // need to handle.
-static void
-WriteRelocations(ArrayRef<WasmRelocationEntry> Relocations,
-                 raw_pwrite_stream &Stream,
-                 DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
-                 uint64_t HeaderSize) {
-  for (const WasmRelocationEntry RelEntry : Relocations) {
-    encodeULEB128(RelEntry.Type, Stream);
+void WasmObjectWriter::writeRelocations(
+    ArrayRef<WasmRelocationEntry> Relocations, uint64_t HeaderSize) {
+  raw_pwrite_stream &Stream = getStream();
+  for (const WasmRelocationEntry& RelEntry : Relocations) {
 
     uint64_t Offset = RelEntry.Offset +
                       RelEntry.FixupSection->getSectionOffset() + HeaderSize;
-    assert(SymbolIndices.count(RelEntry.Symbol));
-    uint32_t Index = SymbolIndices[RelEntry.Symbol];
-    int64_t Addend = RelEntry.Addend;
-
-    switch (RelEntry.Type) {
-    case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
-      encodeULEB128(Offset, Stream);
-      encodeULEB128(Index, Stream);
-      assert(Addend == 0 && "addends not supported for functions");
-      break;
-    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
-    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
-    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
-      encodeULEB128(Offset, Stream);
-      encodeULEB128(Index, Stream);
-      encodeSLEB128(Addend, Stream);
-      break;
-    default:
-      llvm_unreachable("unsupported relocation type");
-    }
-  }
-}
+    uint32_t Index = getRelocationIndexValue(RelEntry);
 
-// Write out the the type relocation records that the linker will
-// need to handle.
-static void WriteTypeRelocations(
-    ArrayRef<WasmRelocationEntry> TypeIndexFixups,
-    ArrayRef<uint32_t> TypeIndexFixupTypes,
-    raw_pwrite_stream &Stream)
-{
-  for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
-    const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
-    uint32_t Type = TypeIndexFixupTypes[i];
-
-    assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
-    assert(Fixup.Addend == 0);
-
-    uint64_t Offset = Fixup.Offset +
-                      Fixup.FixupSection->getSectionOffset();
-
-    encodeULEB128(Fixup.Type, Stream);
+    encodeULEB128(RelEntry.Type, Stream);
     encodeULEB128(Offset, Stream);
-    encodeULEB128(Type, Stream);
+    encodeULEB128(Index, Stream);
+    if (RelEntry.hasAddend())
+      encodeSLEB128(RelEntry.Addend, Stream);
   }
 }
 
@@ -754,7 +727,6 @@ void WasmObjectWriter::writeElemSection(
 
 void WasmObjectWriter::writeCodeSection(
     const MCAssembler &Asm, const MCAsmLayout &Layout,
-    DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
     const SmallVector<WasmFunction, 4> &Functions) {
   if (Functions.empty())
     return;
@@ -789,34 +761,14 @@ void WasmObjectWriter::writeCodeSection(
     Asm.writeSectionData(&FuncSection, Layout);
   }
 
-  // Apply the type index fixups for call_indirect etc. instructions.
-  for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
-    uint32_t Type = TypeIndexFixupTypes[i];
-    unsigned Padding = PaddingFor5ByteULEB128(Type);
-
-    const WasmRelocationEntry &Fixup = TypeIndexFixups[i];
-    assert(Fixup.Addend == 0);
-    assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
-    uint64_t Offset = Fixup.Offset +
-                      Fixup.FixupSection->getSectionOffset();
-
-    uint8_t Buffer[16];
-    unsigned SizeLen = encodeULEB128(Type, Buffer, Padding);
-    assert(SizeLen == 5);
-    getStream().pwrite((char *)Buffer, SizeLen,
-                       Section.ContentsOffset + Offset);
-  }
-
   // Apply fixups.
-  ApplyRelocations(CodeRelocations, getStream(), SymbolIndices,
-                   Section.ContentsOffset);
+  applyRelocations(CodeRelocations, Section.ContentsOffset);
 
   endSection(Section);
 }
 
 uint64_t WasmObjectWriter::writeDataSection(
-    const SmallVector<char, 0> &DataBytes,
-    DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices) {
+    const SmallVector<char, 0> &DataBytes) {
   if (DataBytes.empty())
     return 0;
 
@@ -833,8 +785,7 @@ uint64_t WasmObjectWriter::writeDataSection(
   writeBytes(DataBytes); // data
 
   // Apply fixups.
-  ApplyRelocations(DataRelocations, getStream(), SymbolIndices,
-                   Section.ContentsOffset + HeaderSize);
+  applyRelocations(DataRelocations, Section.ContentsOffset + HeaderSize);
 
   endSection(Section);
   return HeaderSize;
@@ -874,8 +825,7 @@ void WasmObjectWriter::writeNameSection(
   endSection(Section);
 }
 
-void WasmObjectWriter::writeCodeRelocSection(
-    DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices) {
+void WasmObjectWriter::writeCodeRelocSection() {
   // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
   // for descriptions of the reloc sections.
 
@@ -886,17 +836,14 @@ void WasmObjectWriter::writeCodeRelocSection(
   startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.CODE");
 
   encodeULEB128(wasm::WASM_SEC_CODE, getStream());
-  encodeULEB128(CodeRelocations.size() + TypeIndexFixups.size(), getStream());
+  encodeULEB128(CodeRelocations.size(), getStream());
 
-  WriteRelocations(CodeRelocations, getStream(), SymbolIndices, 0);
-  WriteTypeRelocations(TypeIndexFixups, TypeIndexFixupTypes, getStream());
+  writeRelocations(CodeRelocations, 0);
 
   endSection(Section);
 }
 
-void WasmObjectWriter::writeDataRelocSection(
-    DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
-    uint64_t DataSectionHeaderSize) {
+void WasmObjectWriter::writeDataRelocSection(uint64_t DataSectionHeaderSize) {
   // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
   // for descriptions of the reloc sections.
 
@@ -909,8 +856,7 @@ void WasmObjectWriter::writeDataRelocSection(
   encodeULEB128(wasm::WASM_SEC_DATA, getStream());
   encodeULEB128(DataRelocations.size(), getStream());
 
-  WriteRelocations(DataRelocations, getStream(), SymbolIndices,
-                   DataSectionHeaderSize);
+  writeRelocations(DataRelocations, DataSectionHeaderSize);
 
   endSection(Section);
 }
@@ -936,15 +882,12 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   wasm::ValType PtrType = is64Bit() ? wasm::ValType::I64 : wasm::ValType::I32;
 
   // Collect information from the available symbols.
-  DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
-      FunctionTypeIndices;
   SmallVector<WasmFunctionType, 4> FunctionTypes;
   SmallVector<WasmFunction, 4> Functions;
   SmallVector<uint32_t, 4> TableElems;
   SmallVector<WasmGlobal, 4> Globals;
   SmallVector<WasmImport, 4> Imports;
   SmallVector<WasmExport, 4> Exports;
-  DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
   SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
   unsigned NumFuncImports = 0;
   unsigned NumGlobalImports = 0;
@@ -1215,9 +1158,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   }
 
   // Add types for indirect function calls.
-  for (const WasmRelocationEntry &Fixup : TypeIndexFixups) {
-    assert(Fixup.Addend == 0);
-    assert(Fixup.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB);
+  for (const WasmRelocationEntry &Fixup : CodeRelocations) {
+    if (Fixup.Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
+      continue;
 
     WasmFunctionType F;
     F.Returns = Fixup.Symbol->getReturns();
@@ -1227,7 +1170,7 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
     if (Pair.second)
       FunctionTypes.push_back(F);
 
-    TypeIndexFixupTypes.push_back(Pair.first->second);
+    TypeIndices[Fixup.Symbol] = Pair.first->second;
   }
 
   // Write out the Wasm header.
@@ -1242,11 +1185,11 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   writeExportSection(Exports);
   // TODO: Start Section
   writeElemSection(TableElems);
-  writeCodeSection(Asm, Layout, SymbolIndices, Functions);
-  uint64_t DataSectionHeaderSize = writeDataSection(DataBytes, SymbolIndices);
+  writeCodeSection(Asm, Layout, Functions);
+  uint64_t DataSectionHeaderSize = writeDataSection(DataBytes);
   writeNameSection(Functions, Imports, NumFuncImports);
-  writeCodeRelocSection(SymbolIndices);
-  writeDataRelocSection(SymbolIndices, DataSectionHeaderSize);
+  writeCodeRelocSection();
+  writeDataRelocSection(DataSectionHeaderSize);
   writeLinkingMetaDataSection(HasStackPointer, StackPointerGlobal);
 
   // TODO: Translate the .comment section to the output.
index 00d7fc71c497abdbba8d8e97f8e96772bcdbb12f..c773e57402e064b682f59615fb5e4b46e86ec260 100644 (file)
@@ -54,6 +54,11 @@ static bool IsFunctionExpr(const MCExpr *Expr) {
   return false;
 }
 
+static bool IsFunctionType(const MCValue &Target) {
+  const MCSymbolRefExpr *RefA = Target.getSymA();
+  return RefA && RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX;
+}
+
 unsigned WebAssemblyWasmObjectWriter::getRelocType(MCContext &Ctx,
                                                    const MCValue &Target,
                                                    const MCFixup &Fixup,
@@ -71,6 +76,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(MCContext &Ctx,
   case WebAssembly::fixup_code_sleb128_i64:
     llvm_unreachable("fixup_sleb128_i64 not implemented yet");
   case WebAssembly::fixup_code_uleb128_i32:
+    if (IsFunctionType(Target))
+      return wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB;
     if (IsFunction)
       return wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB;
     return wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB;
index 5c794400fa0923d14233af396b4d9c75c801aaac..5fcd9b403811f4b719cd8418e8691c68cf520deb 100644 (file)
@@ -36,16 +36,6 @@ entry:
 ; CHECK-NEXT:       Addend: 0
 ; CHECK-NEXT:     }
 ; CHECK-NEXT:     Relocation {
-; CHECK-NEXT:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
-; CHECK-NEXT:       Offset: 0x2D
-; CHECK-NEXT:       Index: 0x0
-; CHECK-NEXT:     }
-; CHECK-NEXT:     Relocation {
-; CHECK-NEXT:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
-; CHECK-NEXT:       Offset: 0x34
-; CHECK-NEXT:       Index: 0x1
-; CHECK-NEXT:     }
-; CHECK-NEXT:     Relocation {
 ; CHECK-NEXT:       Type: R_WEBASSEMBLY_TYPE_INDEX_LEB (6)
 ; CHECK-NEXT:       Offset: 0x1A
 ; CHECK-NEXT:       Index: 0x1
@@ -55,5 +45,15 @@ entry:
 ; CHECK-NEXT:       Offset: 0x24
 ; CHECK-NEXT:       Index: 0x0
 ; CHECK-NEXT:     }
+; CHECK-NEXT:     Relocation {
+; CHECK-NEXT:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
+; CHECK-NEXT:       Offset: 0x2D
+; CHECK-NEXT:       Index: 0x0
+; CHECK-NEXT:     }
+; CHECK-NEXT:     Relocation {
+; CHECK-NEXT:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
+; CHECK-NEXT:       Offset: 0x34
+; CHECK-NEXT:       Index: 0x1
+; CHECK-NEXT:     }
 ; CHECK-NEXT:   }
 ; CHECK-NEXT: ]