diff --git a/llvm/include/llvm/MC/MCSymbolWasm.h b/llvm/include/llvm/MC/MCSymbolWasm.h index ae512fd27be2..dbb1cb04fc5d 100644 --- a/llvm/include/llvm/MC/MCSymbolWasm.h +++ b/llvm/include/llvm/MC/MCSymbolWasm.h @@ -14,7 +14,7 @@ namespace llvm { class MCSymbolWasm : public MCSymbol { - wasm::WasmSymbolType Type = wasm::WASM_SYMBOL_TYPE_DATA; + Optional Type; bool IsWeak = false; bool IsHidden = false; bool IsComdat = false; @@ -41,12 +41,15 @@ public: void setSize(const MCExpr *SS) { SymbolSize = SS; } bool isFunction() const { return Type == wasm::WASM_SYMBOL_TYPE_FUNCTION; } - bool isData() const { return Type == wasm::WASM_SYMBOL_TYPE_DATA; } + // Data is the default value if not set. + bool isData() const { return !Type || Type == wasm::WASM_SYMBOL_TYPE_DATA; } bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; } bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; } bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; } bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; } - wasm::WasmSymbolType getType() const { return Type; } + + Optional getType() const { return Type; } + void setType(wasm::WasmSymbolType type) { Type = type; } bool isExported() const { diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index dcfb9dd78b82..6b775e12f08d 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -488,10 +488,14 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, const MCSymbol *SectionSymbol = nullptr; const MCSection &SecA = SymA->getSection(); - if (SecA.getKind().isText()) - SectionSymbol = SectionFunctions.find(&SecA)->second; - else + if (SecA.getKind().isText()) { + auto SecSymIt = SectionFunctions.find(&SecA); + if (SecSymIt == SectionFunctions.end()) + report_fatal_error("section doesn\'t have defining symbol"); + SectionSymbol = SecSymIt->second; + } else { SectionSymbol = SecA.getBeginSymbol(); + } if (!SectionSymbol) report_fatal_error("section symbol is required for relocation"); @@ -1458,8 +1462,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, continue; const auto &WS = static_cast(S); - LLVM_DEBUG( - dbgs() << "MCSymbol: " << toString(WS.getType()) << " '" << S << "'" + LLVM_DEBUG(dbgs() + << "MCSymbol: " + << toString(WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA)) + << " '" << S << "'" << " isDefined=" << S.isDefined() << " isExternal=" << S.isExternal() << " isTemporary=" << S.isTemporary() << " isWeak=" << WS.isWeak() << " isHidden=" << WS.isHidden() @@ -1699,7 +1705,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm, wasm::WasmSymbolInfo Info; Info.Name = WS.getName(); - Info.Kind = WS.getType(); + Info.Kind = WS.getType().getValueOr(wasm::WASM_SYMBOL_TYPE_DATA); Info.Flags = Flags; if (!WS.isData()) { assert(WasmIndices.count(&WS) > 0); diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp index 7748bfa7f80f..cf722b0596ee 100644 --- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp +++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp @@ -999,6 +999,20 @@ public: } void doBeforeLabelEmit(MCSymbol *Symbol) override { + // Code below only applies to labels in text sections. + auto CWS = cast(getStreamer().getCurrentSection().first); + if (!CWS || !CWS->getKind().isText()) + return; + + auto WasmSym = cast(Symbol); + // Unlike other targets, we don't allow data in text sections (labels + // declared with .type @object). + if (WasmSym->getType() == wasm::WASM_SYMBOL_TYPE_DATA) { + Parser.Error(Parser.getTok().getLoc(), + "Wasm doesn\'t support data symbols in text sections"); + return; + } + // Start a new section for the next function automatically, since our // object writer expects each function to have its own section. This way // The user can't forget this "convention". @@ -1006,14 +1020,10 @@ public: if (SymName.startswith(".L")) return; // Local Symbol. - // Only create a new text section if we're already in one. // TODO: If the user explicitly creates a new function section, we ignore // its name when we create this one. It would be nice to honor their // choice, while still ensuring that we create one if they forget. // (that requires coordination with WasmAsmParser::parseSectionDirective) - auto CWS = cast(getStreamer().getCurrentSection().first); - if (!CWS || !CWS->getKind().isText()) - return; auto SecName = ".text." + SymName; auto *Group = CWS->getGroup(); @@ -1022,7 +1032,7 @@ public: // for importing comdat functions. But there's no way to specify that in // assembly currently. if (Group) - cast(Symbol)->setComdat(true); + WasmSym->setComdat(true); auto *WS = getContext().getWasmSection(SecName, SectionKind::getText(), Group, MCContext::GenericSectionID, nullptr); diff --git a/llvm/test/MC/WebAssembly/basic-assembly-errors.s b/llvm/test/MC/WebAssembly/basic-assembly-errors.s index ba990f14e11a..45a09654d01d 100644 --- a/llvm/test/MC/WebAssembly/basic-assembly-errors.s +++ b/llvm/test/MC/WebAssembly/basic-assembly-errors.s @@ -4,6 +4,10 @@ # (must be 0.0 or similar) f32.const 0 +# CHECK: Wasm doesn't support data symbols in text sections + .type objerr,@object +objerr: + # CHECK: End of block construct with no start: end_try end_try test0: