[llvm] 5e5b2cb - [WebAssembly] Prevent data inside text sections in assembly

Wouter van Oortmerssen via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 5 13:48:56 PST 2021


Author: Wouter van Oortmerssen
Date: 2021-02-05T13:48:25-08:00
New Revision: 5e5b2cb131c2eec056358d25f946bb208cb8a381

URL: https://github.com/llvm/llvm-project/commit/5e5b2cb131c2eec056358d25f946bb208cb8a381
DIFF: https://github.com/llvm/llvm-project/commit/5e5b2cb131c2eec056358d25f946bb208cb8a381.diff

LOG: [WebAssembly] Prevent data inside text sections in assembly

This is not supported in Wasm, unless the data was encoded instructions, but that wouldn't work with the assembler's other functionality (enforcing nesting etc.).

Fixes: https://bugs.llvm.org/show_bug.cgi?id=48971

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

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCSymbolWasm.h
    llvm/lib/MC/WasmObjectWriter.cpp
    llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
    llvm/test/MC/WebAssembly/basic-assembly-errors.s

Removed: 
    


################################################################################
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<wasm::WasmSymbolType> Type;
   bool IsWeak = false;
   bool IsHidden = false;
   bool IsComdat = false;
@@ -41,12 +41,15 @@ class MCSymbolWasm : public MCSymbol {
   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<wasm::WasmSymbolType> 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<const MCSymbolWasm &>(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 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
   }
 
   void doBeforeLabelEmit(MCSymbol *Symbol) override {
+    // Code below only applies to labels in text sections.
+    auto CWS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
+    if (!CWS || !CWS->getKind().isText())
+      return;
+
+    auto WasmSym = cast<MCSymbolWasm>(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 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
     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<MCSectionWasm>(getStreamer().getCurrentSection().first);
-    if (!CWS || !CWS->getKind().isText())
-      return;
     auto SecName = ".text." + SymName;
 
     auto *Group = CWS->getGroup();
@@ -1022,7 +1032,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
     // for importing comdat functions. But there's no way to specify that in
     // assembly currently.
     if (Group)
-      cast<MCSymbolWasm>(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, at object
+objerr:
+
 # CHECK: End of block construct with no start: end_try
     end_try
 test0:


        


More information about the llvm-commits mailing list