[WebAssembly] MC: Create and use first class section symbols

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

llvm-svn: 331413
This commit is contained in:
Sam Clegg 2018-05-02 23:11:38 +00:00
parent 87cc4dbde7
commit 4d57fbd02a
6 changed files with 148 additions and 211 deletions

View File

@ -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);

View File

@ -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());

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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"