From 4d57fbd02a8cb16045da65e078e72aa68e4ac21e Mon Sep 17 00:00:00 2001
From: Sam Clegg <sbc@chromium.org>
Date: Wed, 2 May 2018 23:11:38 +0000
Subject: [PATCH] [WebAssembly] MC: Create and use first class section symbols

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

llvm-svn: 331413
---
 llvm/lib/MC/MCContext.cpp                |   6 +-
 llvm/lib/MC/MCObjectFileInfo.cpp         |  12 +-
 llvm/lib/MC/MCWasmStreamer.cpp           |  13 +-
 llvm/lib/MC/WasmObjectWriter.cpp         | 252 ++++++++++-------------
 llvm/test/MC/WebAssembly/blockaddress.ll |   4 +-
 llvm/test/MC/WebAssembly/debug-info.ll   |  72 +++----
 6 files changed, 148 insertions(+), 211 deletions(-)

diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ac9259a4d244..317cec5ab5e7 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -516,8 +516,10 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
   StringRef CachedName = Entry.first.SectionName;
 
   MCSymbol *Begin = nullptr;
-  if (BeginSymName)
-    Begin = createTempSymbol(BeginSymName, false);
+  if (BeginSymName) {
+    Begin = createSymbol(BeginSymName, false, false);
+    cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
+  }
 
   MCSectionWasm *Result = new (WasmAllocator.Allocate())
       MCSectionWasm(CachedName, Kind, GroupSym, UniqueID, Begin);
diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp
index 5b3636153d6e..ce9c3529f4fa 100644
--- a/llvm/lib/MC/MCObjectFileInfo.cpp
+++ b/llvm/lib/MC/MCObjectFileInfo.cpp
@@ -866,19 +866,19 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
   DataSection = Ctx->getWasmSection(".data", SectionKind::getData());
 
   // TODO: Set the section types and flags.
-  DwarfLineSection = Ctx->getWasmSection(".debug_line", SectionKind::getMetadata());
+  DwarfLineSection = Ctx->getWasmSection(".debug_line", SectionKind::getMetadata(), ".debug_line");
   DwarfLineStrSection =
       Ctx->getWasmSection(".debug_line_str", SectionKind::getMetadata());
-  DwarfStrSection = Ctx->getWasmSection(".debug_str", SectionKind::getMetadata());
+  DwarfStrSection = Ctx->getWasmSection(".debug_str", SectionKind::getMetadata(), ".debug_str");
   DwarfLocSection = Ctx->getWasmSection(".debug_loc", SectionKind::getMetadata());
-  DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", SectionKind::getMetadata(), "section_abbrev");
+  DwarfAbbrevSection = Ctx->getWasmSection(".debug_abbrev", SectionKind::getMetadata(), ".section_abbrev");
   DwarfARangesSection = Ctx->getWasmSection(".debug_aranges", SectionKind::getMetadata());
-  DwarfRangesSection = Ctx->getWasmSection(".debug_ranges", SectionKind::getMetadata(), "debug_range");
-  DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata(), "debug_macinfo");
+  DwarfRangesSection = Ctx->getWasmSection(".debug_ranges", SectionKind::getMetadata(), ".debug_range");
+  DwarfMacinfoSection = Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata(), ".debug_macinfo");
   DwarfAddrSection = Ctx->getWasmSection(".debug_addr", SectionKind::getMetadata());
   DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata());
   DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata());
-  DwarfInfoSection = Ctx->getWasmSection(".debug_info", SectionKind::getMetadata(), "section_info");
+  DwarfInfoSection = Ctx->getWasmSection(".debug_info", SectionKind::getMetadata(), ".debug_info");
   DwarfFrameSection = Ctx->getWasmSection(".debug_frame", SectionKind::getMetadata());
   DwarfPubNamesSection = Ctx->getWasmSection(".debug_pubnames", SectionKind::getMetadata());
   DwarfPubTypesSection = Ctx->getWasmSection(".debug_pubtypes", SectionKind::getMetadata());
diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp
index 504c72cab972..153ea2523057 100644
--- a/llvm/lib/MC/MCWasmStreamer.cpp
+++ b/llvm/lib/MC/MCWasmStreamer.cpp
@@ -156,17 +156,8 @@ void MCWasmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
 }
 
 void MCWasmStreamer::EmitIdent(StringRef IdentString) {
-  MCSection *Comment = getAssembler().getContext().getWasmSection(
-      ".comment", SectionKind::getMetadata());
-  PushSection();
-  SwitchSection(Comment);
-  if (!SeenIdent) {
-    EmitIntValue(0, 1);
-    SeenIdent = true;
-  }
-  EmitBytes(IdentString);
-  EmitIntValue(0, 1);
-  PopSection();
+  // TODO(sbc): Add the ident section once we support mergable strings
+  // sections in the object format
 }
 
 void MCWasmStreamer::EmitInstToFragment(const MCInst &Inst,
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index ff1ea7880477..407907c0f681 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -244,8 +244,6 @@ class WasmObjectWriter : public MCObjectWriter {
   DenseMap<const MCSymbolWasm *, uint32_t> WasmIndices;
   // Maps data symbols to the Wasm segment and offset/size with the segment.
   DenseMap<const MCSymbolWasm *, wasm::WasmDataReference> DataLocations;
-  // Maps section symbols to the section.
-  DenseMap<const MCSymbolWasm *, const MCSectionWasm *> CustomSectionSymbols;
 
   // Stores output data (index, relocations, content offset) for custom
   // section.
@@ -295,7 +293,6 @@ private:
     FunctionTypes.clear();
     Globals.clear();
     DataSegments.clear();
-    CustomSectionSymbols.clear();
     MCObjectWriter::reset();
     NumFunctionImports = 0;
     NumGlobalImports = 0;
@@ -433,11 +430,6 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
   if (FixupSection.getSectionName().startswith(".init_array"))
     return;
 
-  // TODO: Add support for non-debug metadata sections?
-  if (FixupSection.getKind().isMetadata() &&
-      !FixupSection.getSectionName().startswith(".debug_"))
-    return;
-
   if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
     assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
            "Should not have constructed this");
@@ -495,36 +487,50 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
   // be negative and don't wrap.
   FixedValue = 0;
 
-  if (SymA)
-    SymA->setUsedInReloc();
-
+  unsigned Type = getRelocType(Target, Fixup);
   assert(!IsPCRel);
   assert(SymA);
 
-  unsigned Type = getRelocType(Target, Fixup);
+  // Absolute offset within a section or a function.
+  // Currently only supported for for metadata sections.
+  // See: test/MC/WebAssembly/blockaddress.ll
+  if (Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 ||
+      Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32) {
+    if (!FixupSection.getKind().isMetadata())
+      report_fatal_error("relocations for function or section offsets are "
+                         "only supported in metadata sections");
+
+    const MCSymbol *SectionSymbol = nullptr;
+    const MCSection &SecA = SymA->getSection();
+    if (SecA.getKind().isText())
+      SectionSymbol = SecA.begin()->getAtom();
+    else
+      SectionSymbol = SecA.getBeginSymbol();
+    if (!SectionSymbol)
+      report_fatal_error("section symbol is required for relocation");
+
+    C += Layout.getSymbolOffset(*SymA);
+    SymA = cast<MCSymbolWasm>(SectionSymbol);
+  }
+
+  // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB are required to be
+  // against a named symbol.
+  if (Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB) {
+    if (SymA->getName().empty())
+      report_fatal_error("relocations against un-named temporaries are not yet "
+                         "supported by wasm");
+
+    SymA->setUsedInReloc();
+  }
 
   WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
   DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");
 
-  // Relocation other than R_WEBASSEMBLY_TYPE_INDEX_LEB,
-  // R_WEBASSEMBLY_SECTION_OFFSET_I32 or R_WEBASSEMBLY_FUNCTION_OFFSET_I32
-  // are currently required to be against a named symbol.
-  // TODO(sbc): Add support for relocations against unnamed temporaries such
-  // as those generated by llvm's `blockaddress`.
-  // See: test/MC/WebAssembly/blockaddress.ll
-  if (SymA->getName().empty() &&
-      !(Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB ||
-        Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32 ||
-        Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32))
-    report_fatal_error("relocations against un-named temporaries are not yet "
-                       "supported by wasm");
-
   if (FixupSection.isWasmData()) {
     DataRelocations.push_back(Rec);
   } else if (FixupSection.getKind().isText()) {
     CodeRelocations.push_back(Rec);
   } else if (FixupSection.getKind().isMetadata()) {
-    assert(FixupSection.getSectionName().startswith(".debug_"));
     CustomSectionsRelocations[&FixupSection].push_back(Rec);
   } else {
     llvm_unreachable("unexpected section type");
@@ -591,15 +597,12 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
       report_fatal_error("symbol not found in wasm index space: " +
                          RelEntry.Symbol->getName());
     return WasmIndices[RelEntry.Symbol];
-  case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
+  case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
+  case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
     const auto &Section =
         static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection());
     return Section.getSectionOffset() + RelEntry.Addend;
   }
-  case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
-    const auto &Section = *CustomSectionSymbols.find(RelEntry.Symbol)->second;
-    return Section.getSectionOffset() + RelEntry.Addend;
-  }
   case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
   case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
   case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
@@ -1033,49 +1036,10 @@ void WasmObjectWriter::writeCustomSections(const MCAssembler &Asm,
     CustomSection.OutputIndex = Section.Index;
 
     endSection(Section);
-  }
-}
-
-void WasmObjectWriter::updateCustomSectionRelocations(
-    const SmallVector<WasmFunction, 4> &Functions, const MCAsmLayout &Layout) {
-  std::map<const MCSection *, const MCSymbolWasm *> SectionSymbols;
-  for (const auto &P : CustomSectionSymbols)
-    SectionSymbols[P.second] = P.first;
-  std::map<const MCSection *, const MCSymbolWasm *> FuncSymbols;
-  for (const auto &FuncInfo : Functions)
-    FuncSymbols[&FuncInfo.Sym->getSection()] = FuncInfo.Sym;
-
-  // Patch relocation records for R_WEBASSEMBLY_FUNCTION_OFFSET_I32 and
-  // R_WEBASSEMBLY_SECTION_OFFSET_I32. The Addend is stuffed the offset from
-  // the beginning of the function or custom section -- all such relocations
-  // target the function or custom section starts.
-  for (auto &Section : CustomSections) {
-    auto &Relocations = CustomSectionsRelocations[Section.Section];
-    for (WasmRelocationEntry &RelEntry : Relocations) {
-      switch (RelEntry.Type) {
-      case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32: {
-        assert(RelEntry.hasAddend());
-        auto &Section =
-            static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection());
-        RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
-        RelEntry.Symbol = FuncSymbols[&Section];
-        break;
-      }
-      case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32: {
-        assert(RelEntry.hasAddend());
-        auto &Section =
-            static_cast<MCSectionWasm &>(RelEntry.Symbol->getSection());
-        RelEntry.Addend += Layout.getSymbolOffset(*RelEntry.Symbol);
-        RelEntry.Symbol = SectionSymbols[&Section];
-        break;
-      }
-      default:
-        break;
-      }
-    }
 
     // Apply fixups.
-    applyRelocations(Relocations, Section.OutputContentsOffset);
+    auto &Relocations = CustomSectionsRelocations[CustomSection.Section];
+    applyRelocations(Relocations, CustomSection.OutputContentsOffset);
   }
 }
 
@@ -1104,6 +1068,25 @@ uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm& Symbol) {
   return Pair.first->second;
 }
 
+static bool isInSymtab(const MCSymbolWasm &Sym) {
+  if (Sym.isUsedInReloc())
+    return true;
+
+  if (Sym.isComdat() && !Sym.isDefined())
+    return false;
+
+  if (Sym.isTemporary() && Sym.getName().empty())
+    return false;
+
+  if (Sym.isTemporary() && Sym.isData() && !Sym.getSize())
+    return false;
+
+  if (Sym.isSection())
+    return false;
+
+  return true;
+}
+
 void WasmObjectWriter::writeObject(MCAssembler &Asm,
                                    const MCAsmLayout &Layout) {
   DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
@@ -1181,78 +1164,55 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
     }
   }
 
-  // Populate DataSegments, which must be done before populating DataLocations.
+  // Populate DataSegments and CustomSections, which must be done before
+  // populating DataLocations.
   for (MCSection &Sec : Asm) {
     auto &Section = static_cast<MCSectionWasm &>(Sec);
-
-    if (Section.getSectionName().startswith(".custom_section.")) {
-      if (Section.getFragmentList().empty())
-        continue;
-      if (Section.getFragmentList().size() != 1)
-        report_fatal_error(
-            "only one .custom_section section fragment supported");
-      const MCFragment &Frag = *Section.begin();
-      if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
-        report_fatal_error("only data supported in .custom_section section");
-      const auto &DataFrag = cast<MCDataFragment>(Frag);
-      if (!DataFrag.getFixups().empty())
-        report_fatal_error("fixups not supported in .custom_section section");
-      StringRef UserName = Section.getSectionName().substr(16);
-      CustomSections.emplace_back(UserName, &Section);
-      continue;
-    }
-
-    if (!Section.isWasmData())
-      continue;
+    StringRef SectionName = Section.getSectionName();
 
     // .init_array sections are handled specially elsewhere.
-    if (cast<MCSectionWasm>(Sec).getSectionName().startswith(".init_array"))
+    if (SectionName.startswith(".init_array"))
       continue;
 
-    uint32_t SegmentIndex = DataSegments.size();
-    DataSize = alignTo(DataSize, Section.getAlignment());
-    DataSegments.emplace_back();
-    WasmDataSegment &Segment = DataSegments.back();
-    Segment.Name = Section.getSectionName();
-    Segment.Offset = DataSize;
-    Segment.Section = &Section;
-    addData(Segment.Data, Section);
-    Segment.Alignment = Section.getAlignment();
-    Segment.Flags = 0;
-    DataSize += Segment.Data.size();
-    Section.setSegmentIndex(SegmentIndex);
+    // Code is handled separately
+    if (Section.getKind().isText())
+      continue;
 
-    if (const MCSymbolWasm *C = Section.getGroup()) {
-      Comdats[C->getName()].emplace_back(
-          WasmComdatEntry{wasm::WASM_COMDAT_DATA, SegmentIndex});
+    if (Section.isWasmData()) {
+      uint32_t SegmentIndex = DataSegments.size();
+      DataSize = alignTo(DataSize, Section.getAlignment());
+      DataSegments.emplace_back();
+      WasmDataSegment &Segment = DataSegments.back();
+      Segment.Name = SectionName;
+      Segment.Offset = DataSize;
+      Segment.Section = &Section;
+      addData(Segment.Data, Section);
+      Segment.Alignment = Section.getAlignment();
+      Segment.Flags = 0;
+      DataSize += Segment.Data.size();
+      Section.setSegmentIndex(SegmentIndex);
+
+      if (const MCSymbolWasm *C = Section.getGroup()) {
+        Comdats[C->getName()].emplace_back(
+            WasmComdatEntry{wasm::WASM_COMDAT_DATA, SegmentIndex});
+      }
+    } else {
+      // Create custom sections
+      assert(Sec.getKind().isMetadata());
+
+      StringRef Name = SectionName;
+
+      // For user-defined custom sections, strip the prefix
+      if (Name.startswith(".custom_section."))
+        Name = Name.substr(strlen(".custom_section."));
+
+      MCSymbol* Begin = Sec.getBeginSymbol();
+      if (Begin)
+        WasmIndices[cast<MCSymbolWasm>(Begin)] = CustomSections.size();
+      CustomSections.emplace_back(Name, &Section);
     }
   }
 
-  // Create symbols for debug/custom sections.
-  for (MCSection &Sec : Asm) {
-    auto &DebugSection = static_cast<MCSectionWasm &>(Sec);
-    StringRef SectionName = DebugSection.getSectionName();
-
-    // TODO: Add support for non-debug metadata sections?
-    if (!Sec.getKind().isMetadata() || !SectionName.startswith(".debug_"))
-      continue;
-
-    uint32_t ElementIndex = CustomSections.size();
-    CustomSections.emplace_back(SectionName, &DebugSection);
-
-    MCSymbolWasm *SectionSym =
-        cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SectionName));
-    CustomSectionSymbols[SectionSym] = &DebugSection;
-
-    wasm::WasmSymbolInfo Info;
-    Info.Name = SectionSym->getName();
-    Info.Kind = wasm::WASM_SYMBOL_TYPE_SECTION;
-    Info.Flags = wasm::WASM_SYMBOL_BINDING_LOCAL;
-    Info.ElementIndex = ElementIndex;
-    SymbolIndices[SectionSym] = SymbolInfos.size();
-    SymbolInfos.emplace_back(Info);
-  }
-
   // Populate WasmIndices and DataLocations for defined symbols.
   for (const MCSymbol &S : Asm.symbols()) {
     // Ignore unnamed temporary symbols, which aren't ever exported, imported,
@@ -1380,12 +1340,9 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   // Finally, populate the symbol table itself, in its "natural" order.
   for (const MCSymbol &S : Asm.symbols()) {
     const auto &WS = static_cast<const MCSymbolWasm &>(S);
-    if (WS.isTemporary() && WS.getName().empty())
-      continue;
-    if (WS.isComdat() && !WS.isDefined())
-      continue;
-    if (WS.isTemporary() && WS.isData() && !WS.getSize())
+    if (!isInSymtab(WS))
       continue;
+    DEBUG(dbgs() << "adding to symtab: " << WS << "\n");
 
     uint32_t Flags = 0;
     if (WS.isWeak())
@@ -1401,10 +1358,13 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
     Info.Name = WS.getName();
     Info.Kind = WS.getType();
     Info.Flags = Flags;
-    if (!WS.isData())
+    if (!WS.isData()) {
+      assert(WasmIndices.count(&WS) > 0);
       Info.ElementIndex = WasmIndices.find(&WS)->second;
-    else if (WS.isDefined())
+    } else if (WS.isDefined()) {
+      assert(DataLocations.count(&WS) > 0);
       Info.DataRef = DataLocations.find(&WS)->second;
+    }
     SymbolIndices[&WS] = SymbolInfos.size();
     SymbolInfos.emplace_back(Info);
   }
@@ -1455,10 +1415,13 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
     if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
       report_fatal_error("only data supported in .init_array section");
     uint16_t Priority = UINT16_MAX;
-    if (WS.getSectionName().size() != 11) {
-      if (WS.getSectionName()[11] != '.')
+    unsigned PrefixLength = strlen(".init_array");
+    if (WS.getSectionName().size() > PrefixLength) {
+      if (WS.getSectionName()[PrefixLength] != '.')
         report_fatal_error(".init_array section priority should start with '.'");
-      if (WS.getSectionName().substr(12).getAsInteger(10, Priority))
+      if (WS.getSectionName()
+              .substr(PrefixLength + 1)
+              .getAsInteger(10, Priority))
         report_fatal_error("invalid .init_array section priority");
     }
     const auto &DataFrag = cast<MCDataFragment>(Frag);
@@ -1499,7 +1462,6 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
   writeCodeSection(Asm, Layout, Functions);
   writeDataSection();
   writeCustomSections(Asm, Layout);
-  updateCustomSectionRelocations(Functions, Layout);
   writeLinkingMetaDataSection(SymbolInfos, InitFuncs, Comdats);
   writeRelocSection(CodeSectionIndex, "CODE", CodeRelocations);
   writeRelocSection(DataSectionIndex, "DATA", DataRelocations);
diff --git a/llvm/test/MC/WebAssembly/blockaddress.ll b/llvm/test/MC/WebAssembly/blockaddress.ll
index 79bc1b8fcfce..8d285254e7f7 100644
--- a/llvm/test/MC/WebAssembly/blockaddress.ll
+++ b/llvm/test/MC/WebAssembly/blockaddress.ll
@@ -1,6 +1,6 @@
 ; TODO(sbc): Make this test pass by adding support for unnamed tempoaries
 ; in wasm relocations.
-; RUN: not llc -filetype=obj %s
+; RUN: not llc -filetype=obj %s 2>&1 | FileCheck %s
 
 target triple = "wasm32-unknown-unknown-wasm"
 
@@ -13,3 +13,5 @@ entry:
 addr:
   ret i32 0
 }
+
+; CHECK: LLVM ERROR: relocations for function or section offsets are only supported in metadata sections
diff --git a/llvm/test/MC/WebAssembly/debug-info.ll b/llvm/test/MC/WebAssembly/debug-info.ll
index 40126a7f2881..cbb232405615 100644
--- a/llvm/test/MC/WebAssembly/debug-info.ll
+++ b/llvm/test/MC/WebAssembly/debug-info.ll
@@ -96,38 +96,38 @@
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
-; CHECK-NEXT:    Size: 100
+; CHECK-NEXT:    Size: 88
 ; CHECK-NEXT:    Offset: 733
 ; CHECK-NEXT:    Name: linking
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
 ; CHECK-NEXT:    Size: 9
-; CHECK-NEXT:    Offset: 847
+; CHECK-NEXT:    Offset: 835
 ; CHECK-NEXT:    Name: reloc.DATA
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
 ; CHECK-NEXT:    Size: 58
-; CHECK-NEXT:    Offset: 873
+; CHECK-NEXT:    Offset: 861
 ; CHECK-NEXT:    Name: reloc..debug_info
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
 ; CHECK-NEXT:    Size: 6
-; CHECK-NEXT:    Offset: 955
+; CHECK-NEXT:    Offset: 943
 ; CHECK-NEXT:    Name: reloc..debug_pubnames
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
 ; CHECK-NEXT:    Size: 6
-; CHECK-NEXT:    Offset: 989
+; CHECK-NEXT:    Offset: 977
 ; CHECK-NEXT:    Name: reloc..debug_pubtypes
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:  Section {
 ; CHECK-NEXT:    Type: CUSTOM (0x0)
 ; CHECK-NEXT:    Size: 6
-; CHECK-NEXT:    Offset: 1023
+; CHECK-NEXT:    Offset: 1011
 ; CHECK-NEXT:    Name: reloc..debug_line
 ; CHECK-NEXT:  }
 ; CHECK-NEXT:]
@@ -163,46 +163,6 @@
 ; CHECK-NEXT:]
 ; CHECK-NEXT:Symbols [
 ; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_str
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_abbrev
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_info
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_ranges
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_macinfo
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_pubnames
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_pubtypes
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
-; CHECK-NEXT:    Name: .debug_line
-; CHECK-NEXT:    Type: SECTION (0x3)
-; CHECK-NEXT:    Flags: 0x2
-; CHECK-NEXT:  }
-; CHECK-NEXT:  Symbol {
 ; CHECK-NEXT:    Name: f2
 ; CHECK-NEXT:    Type: FUNCTION (0x0)
 ; CHECK-NEXT:    Flags: 0x4
@@ -222,6 +182,26 @@
 ; CHECK-NEXT:    Type: DATA (0x1)
 ; CHECK-NEXT:    Flags: 0x4
 ; CHECK-NEXT:  }
+; CHECK-NEXT:  Symbol {
+; CHECK-NEXT:    Name: .debug_str
+; CHECK-NEXT:    Type: SECTION (0x3)
+; CHECK-NEXT:    Flags: 0x2
+; CHECK-NEXT:  }
+; CHECK-NEXT:  Symbol {
+; CHECK-NEXT:    Name: .debug_abbrev
+; CHECK-NEXT:    Type: SECTION (0x3)
+; CHECK-NEXT:    Flags: 0x2
+; CHECK-NEXT:  }
+; CHECK-NEXT:  Symbol {
+; CHECK-NEXT:    Name: .debug_info
+; CHECK-NEXT:    Type: SECTION (0x3)
+; CHECK-NEXT:    Flags: 0x2
+; CHECK-NEXT:  }
+; CHECK-NEXT:  Symbol {
+; CHECK-NEXT:    Name: .debug_line
+; CHECK-NEXT:    Type: SECTION (0x3)
+; CHECK-NEXT:    Flags: 0x2
+; CHECK-NEXT:  }
 ; CHECK-NEXT:]
 
 target triple = "wasm32-unknown-unknown-wasm"