[llvm] r355321 - [WebAssembly] Add support for data sections in the assembler.

Wouter van Oortmerssen via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 4 09:18:04 PST 2019


Author: aardappel
Date: Mon Mar  4 09:18:04 2019
New Revision: 355321

URL: http://llvm.org/viewvc/llvm-project?rev=355321&view=rev
Log:
[WebAssembly] Add support for data sections in the assembler.

Summary:
This is quite minimal so far, introduce them with .section,
fill them with .int8 or .asciz, end with .size

Reviewers: dschuff, sbc100, aheejin

Subscribers: jgravelle-google, sunfish, llvm-commits

Tags: #llvm

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

Added:
    llvm/trunk/test/MC/WebAssembly/data-section.s
Modified:
    llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
    llvm/trunk/test/MC/WebAssembly/basic-assembly.s

Modified: llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/WasmAsmParser.cpp Mon Mar  4 09:18:04 2019
@@ -130,11 +130,27 @@ public:
     if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") ||
         expect(AsmToken::EndOfStatement, "eol"))
       return true;
-    // This is done automatically by the assembler for text sections currently,
-    // so we don't need to emit that here. This is what it would do (and may
-    // be needed later for other section types):
-    // auto WS = getContext().getWasmSection(Name, SectionKind::getText());
-    // getStreamer().SwitchSection(WS);
+    struct SectionType {
+      const char *Name;
+      SectionKind Kind;
+    };
+    static SectionType SectionTypes[] = {
+        { ".text", SectionKind::getText() },
+        { ".rodata", SectionKind::getReadOnly() },
+        { ".data", SectionKind::getData() },
+        // TODO: add more types.
+    };
+    for (size_t I = 0; I < sizeof(SectionTypes) / sizeof(SectionType); I++) {
+      if (Name.startswith(SectionTypes[I].Name)) {
+        auto WS = getContext().getWasmSection(Name, SectionTypes[I].Kind);
+        getStreamer().SwitchSection(WS);
+        return false;
+      }
+    }
+    // Not found, just ignore this section.
+    // For code in a text section WebAssemblyAsmParser automatically adds
+    // one section per function, so they're optional to be specified with
+    // this directive.
     return false;
   }
 
@@ -153,9 +169,8 @@ public:
     if (expect(AsmToken::EndOfStatement, "eol"))
       return true;
     // This is done automatically by the assembler for functions currently,
-    // so we don't need to emit that here. This is what it would do:
-    (void)Sym;
-    // getStreamer().emitELFSize(Sym, Expr);
+    // so this is only currently needed for data sections:
+    getStreamer().emitELFSize(Sym, Expr);
     return false;
   }
 

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Mon Mar  4 09:18:04 2019
@@ -1348,7 +1348,7 @@ uint64_t WasmObjectWriter::writeObject(M
       LLVM_DEBUG(dbgs() << "  -> function index: " << Index << "\n");
 
     } else if (WS.isData()) {
-      if (WS.isTemporary() && !WS.getSize())
+      if (!isInSymtab(WS))
         continue;
 
       if (!WS.isDefined()) {

Modified: llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp Mon Mar  4 09:18:04 2019
@@ -172,6 +172,7 @@ class WebAssemblyAsmParser final : publi
     FunctionLocals,
     Instructions,
     EndFunction,
+    DataSection,
   } CurrentState = FileStart;
 
   // For ensuring blocks are properly nested.
@@ -552,6 +553,17 @@ public:
     return false;
   }
 
+  bool CheckDataSection() {
+    if (CurrentState != DataSection) {
+      auto WS = cast<MCSectionWasm>(getStreamer().getCurrentSection().first);
+      if (WS && WS->getKind().isText())
+        return error("data directive must occur in a data segment: ",
+                     Lexer.getTok());
+    }
+    CurrentState = DataSection;
+    return false;
+  }
+
   // This function processes wasm-specific directives streamed to
   // WebAssemblyTargetStreamer, all others go to the generic parser
   // (see WasmAsmParser).
@@ -650,6 +662,25 @@ public:
       return expect(AsmToken::EndOfStatement, "EOL");
     }
 
+    if (DirectiveID.getString() == ".int8") {
+      if (CheckDataSection()) return true;
+      int64_t V;
+      if (Parser.parseAbsoluteExpression(V))
+        return error("Cannot parse int8 constant: ", Lexer.getTok());
+      // TODO: error if value doesn't fit?
+      Out.EmitIntValue(static_cast<uint64_t>(V), 1);
+      return expect(AsmToken::EndOfStatement, "EOL");
+    }
+
+    if (DirectiveID.getString() == ".asciz") {
+      if (CheckDataSection()) return true;
+      std::string S;
+      if (Parser.parseEscapedString(S))
+        return error("Cannot parse string constant: ", Lexer.getTok());
+      Out.EmitBytes(StringRef(S.c_str(), S.length() + 1));
+      return expect(AsmToken::EndOfStatement, "EOL");
+    }
+
     return true; // We didn't process this directive.
   }
 
@@ -717,9 +748,10 @@ public:
   void onEndOfFunction() {
     // Automatically output a .size directive, so it becomes optional for the
     // user.
+    if (!LastFunctionLabel) return;
     auto TempSym = getContext().createLinkerPrivateTempSymbol();
     getStreamer().EmitLabel(TempSym);
-    auto Start = MCSymbolRefExpr::create(LastLabel, getContext());
+    auto Start = MCSymbolRefExpr::create(LastFunctionLabel, getContext());
     auto End = MCSymbolRefExpr::create(TempSym, getContext());
     auto Expr =
         MCBinaryExpr::create(MCBinaryExpr::Sub, End, Start, getContext());

Modified: llvm/trunk/test/MC/WebAssembly/basic-assembly.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/basic-assembly.s?rev=355321&r1=355320&r2=355321&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/basic-assembly.s (original)
+++ llvm/trunk/test/MC/WebAssembly/basic-assembly.s Mon Mar  4 09:18:04 2019
@@ -77,12 +77,19 @@ test0:
 .LBB0_4:
     end_block
     end_try
-    i32.const 0
+    i32.const .L.str
     throw 0
 .LBB0_5:
     #i32.trunc_sat_f32_s
     global.get  __stack_pointer
     end_function
+
+    .section	.rodata..L.str,"",@
+.L.str:
+    .int8	'H'
+    .asciz	"ello, World!"
+    .size	.L.str, 14
+
     .globaltype	__stack_pointer, i32
 
 # CHECK:           .text
@@ -154,10 +161,15 @@ test0:
 # CHECK-NEXT:  .LBB0_4:
 # CHECK-NEXT:      end_block
 # CHECK-NEXT:      end_try
-# CHECK-NEXT:      i32.const 0
+# CHECK-NEXT:      i32.const .L.str
 # CHECK-NEXT:      throw 0
 # CHECK-NEXT:  .LBB0_5:
 # CHECK-NEXT:      global.get  __stack_pointer
 # CHECK-NEXT:      end_function
 
+# CHECK:	    .section	.rodata..L.str,"",@
+# CHECK-NEXT:.L.str:
+# CHECK-NEXT:	.int8	72
+# CHECK-NEXT:	.asciz	"ello, World!"
+
 # CHECK:           .globaltype	__stack_pointer, i32

Added: llvm/trunk/test/MC/WebAssembly/data-section.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/data-section.s?rev=355321&view=auto
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/data-section.s (added)
+++ llvm/trunk/test/MC/WebAssembly/data-section.s Mon Mar  4 09:18:04 2019
@@ -0,0 +1,94 @@
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | FileCheck %s
+# Check that it converts to .o without errors:
+# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+unimplemented-simd128,+nontrapping-fptoint,+exception-handling < %s | obj2yaml | FileCheck -check-prefix=BIN %s
+
+# Minimal test for data sections.
+
+test0:
+    .functype   test0 () -> (i32)
+    i32.const .L.str
+.Ltestlabel:
+    end_function
+
+    .section	.rodata..L.str,"",@
+.L.str:
+    .int8	100
+    .size	.L.str, 1
+
+
+# CHECK:           .text
+# CHECK-LABEL: test0:
+# CHECK-NEXT:      .functype test0 () -> (i32)
+# CHECK-NEXT:      i32.const .L.str
+# CHECK-NEXT:  .Ltestlabel:
+# CHECK-NEXT:      end_function
+
+# CHECK:	    .section	.rodata..L.str,"",@
+# CHECK-NEXT:.L.str:
+# CHECK-NEXT:	.int8	100
+
+
+# BIN:      --- !WASM
+# BIN-NEXT: FileHeader:
+# BIN-NEXT:   Version:         0x00000001
+# BIN-NEXT: Sections:
+# BIN-NEXT:   - Type:            TYPE
+# BIN-NEXT:     Signatures:
+# BIN-NEXT:       - Index:           0
+# BIN-NEXT:         ReturnType:      I32
+# BIN-NEXT:         ParamTypes:      []
+# BIN-NEXT:   - Type:            IMPORT
+# BIN-NEXT:     Imports:
+# BIN-NEXT:       - Module:          env
+# BIN-NEXT:         Field:           __linear_memory
+# BIN-NEXT:         Kind:            MEMORY
+# BIN-NEXT:         Memory:
+# BIN-NEXT:           Initial:         0x00000001
+# BIN-NEXT:       - Module:          env
+# BIN-NEXT:         Field:           __indirect_function_table
+# BIN-NEXT:         Kind:            TABLE
+# BIN-NEXT:         Table:
+# BIN-NEXT:           ElemType:        FUNCREF
+# BIN-NEXT:           Limits:
+# BIN-NEXT:             Initial:         0x00000000
+# BIN-NEXT:   - Type:            FUNCTION
+# BIN-NEXT:     FunctionTypes:   [ 0 ]
+# BIN-NEXT:   - Type:            CODE
+# BIN-NEXT:     Relocations:
+# BIN-NEXT:       - Type:            R_WASM_MEMORY_ADDR_SLEB
+# BIN-NEXT:         Index:           1
+# BIN-NEXT:         Offset:          0x00000004
+# BIN-NEXT:     Functions:
+# BIN-NEXT:       - Index:           0
+# BIN-NEXT:         Locals:          []
+# BIN-NEXT:         Body:            4180808080000B
+# BIN-NEXT:   - Type:            DATA
+# BIN-NEXT:     Segments:
+# BIN-NEXT:       - SectionOffset:   6
+# BIN-NEXT:         InitFlags:       0
+# BIN-NEXT:         Offset:
+# BIN-NEXT:           Opcode:          I32_CONST
+# BIN-NEXT:           Value:           0
+# BIN-NEXT:         Content:         '64'
+# BIN-NEXT:   - Type:            CUSTOM
+# BIN-NEXT:     Name:            linking
+# BIN-NEXT:     Version:         2
+# BIN-NEXT:     SymbolTable:
+# BIN-NEXT:       - Index:           0
+# BIN-NEXT:         Kind:            FUNCTION
+# BIN-NEXT:         Name:            test0
+# BIN-NEXT:         Flags:           [ BINDING_LOCAL ]
+# BIN-NEXT:         Function:        0
+# BIN-NEXT:       - Index:           1
+# BIN-NEXT:         Kind:            DATA
+# BIN-NEXT:         Name:            .L.str
+# BIN-NEXT:         Flags:           [ BINDING_LOCAL ]
+# BIN-NEXT:         Segment:         0
+# BIN-NEXT:         Size:            1
+# BIN-NEXT:     SegmentInfo:
+# BIN-NEXT:       - Index:           0
+# BIN-NEXT:         Name:            .rodata..L.str
+# BIN-NEXT:         Alignment:       0
+# BIN-NEXT:         Flags:           [  ]
+# BIN-NEXT: ...
+




More information about the llvm-commits mailing list