From fa82617e4177d456c0b80a53915b6bea65832419 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 19 Feb 2019 22:56:19 +0000 Subject: [PATCH] [WebAssembly] Update MC for bulk memory Summary: Rename MemoryIndex to InitFlags and implement logic for determining data segment layout in ObjectYAML and MC. Also adds a "passive" flag for the .section assembler directive although this cannot be assembled yet because the assembler does not support data sections. Reviewers: sbc100, aardappel, aheejin, dschuff Subscribers: jgravelle-google, hiraditya, sunfish, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57938 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@354397 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/BinaryFormat/Wasm.h | 12 +++-- include/llvm/MC/MCSectionWasm.h | 11 +++++ include/llvm/ObjectYAML/WasmYAML.h | 3 +- lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 17 +++++-- lib/MC/MCParser/WasmAsmParser.cpp | 46 +++++++++++++++++-- lib/MC/MCSectionWasm.cpp | 3 +- lib/MC/WasmObjectWriter.cpp | 20 +++++--- lib/Object/WasmObjectFile.cpp | 17 +++++-- lib/ObjectYAML/WasmYAML.cpp | 14 +++++- .../WebAssembly/WebAssemblyAsmPrinter.cpp | 1 + test/CodeGen/WebAssembly/global.ll | 9 ++-- test/CodeGen/WebAssembly/vtable.ll | 6 +-- test/MC/WebAssembly/bss.ll | 10 ++-- test/MC/WebAssembly/comdat.ll | 4 +- test/MC/WebAssembly/debug-info.ll | 2 +- test/MC/WebAssembly/explicit-sections.ll | 14 +++--- test/MC/WebAssembly/external-data.ll | 8 ++-- test/MC/WebAssembly/external-func-address.ll | 2 +- test/MC/WebAssembly/global-ctor-dtor.ll | 6 +-- test/MC/WebAssembly/init-flags.ll | 25 ++++++++++ test/MC/WebAssembly/reloc-data.ll | 2 +- test/MC/WebAssembly/unnamed-data.ll | 18 ++++---- test/MC/WebAssembly/weak-alias.ll | 8 ++-- test/ObjectYAML/wasm/data_section.yaml | 30 +++++++++--- test/ObjectYAML/wasm/linking_section.yaml | 4 +- test/tools/llvm-nm/wasm/exports.yaml | 2 +- test/tools/llvm-nm/wasm/local-symbols.ll | 2 +- test/tools/llvm-nm/wasm/weak-symbols.yaml | 2 +- .../llvm-objdump/WebAssembly/relocations.test | 2 +- tools/obj2yaml/wasm2yaml.cpp | 3 +- tools/yaml2obj/yaml2wasm.cpp | 7 ++- 31 files changed, 227 insertions(+), 83 deletions(-) create mode 100644 test/MC/WebAssembly/init-flags.ll diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 51f6ab2594b..7848be1cbfa 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -131,12 +131,13 @@ struct WasmFunction { }; struct WasmDataSegment { - uint32_t MemoryIndex; - WasmInitExpr Offset; + uint32_t InitFlags; + uint32_t MemoryIndex; // present if InitFlags & WASM_SEGMENT_HAS_MEMINDEX + WasmInitExpr Offset; // present if InitFlags & WASM_SEGMENT_IS_PASSIVE == 0 ArrayRef Content; StringRef Name; // from the "segment info" section uint32_t Alignment; - uint32_t Flags; + uint32_t LinkerFlags; uint32_t Comdat; // from the "comdat info" section }; @@ -247,6 +248,11 @@ enum : unsigned { WASM_LIMITS_FLAG_IS_SHARED = 0x2, }; +enum : unsigned { + WASM_SEGMENT_IS_PASSIVE = 0x01, + WASM_SEGMENT_HAS_MEMINDEX = 0x02, +}; + // Kind codes used in the custom "name" section enum : unsigned { WASM_NAMES_FUNCTION = 0x1, diff --git a/include/llvm/MC/MCSectionWasm.h b/include/llvm/MC/MCSectionWasm.h index 0e576b7ba40..1adc8126492 100644 --- a/include/llvm/MC/MCSectionWasm.h +++ b/include/llvm/MC/MCSectionWasm.h @@ -42,6 +42,9 @@ class MCSectionWasm final : public MCSection { // segment uint32_t SegmentIndex = 0; + // Whether this data segment is passive + bool IsPassive = false; + friend class MCContext; MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group, unsigned UniqueID, MCSymbol *Begin) @@ -75,6 +78,14 @@ public: uint32_t getSegmentIndex() const { return SegmentIndex; } void setSegmentIndex(uint32_t Index) { SegmentIndex = Index; } + bool getPassive() const { + assert(isWasmData()); + return IsPassive; + } + void setPassive(bool V = true) { + assert(isWasmData()); + IsPassive = V; + } static bool classof(const MCSection *S) { return S->getVariant() == SV_Wasm; } }; diff --git a/include/llvm/ObjectYAML/WasmYAML.h b/include/llvm/ObjectYAML/WasmYAML.h index f5260bbb1ed..1d69d78e613 100644 --- a/include/llvm/ObjectYAML/WasmYAML.h +++ b/include/llvm/ObjectYAML/WasmYAML.h @@ -111,8 +111,9 @@ struct Relocation { }; struct DataSegment { - uint32_t MemoryIndex; uint32_t SectionOffset; + uint32_t InitFlags; + uint32_t MemoryIndex; wasm::WasmInitExpr Offset; yaml::BinaryRef Content; }; diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index a7cdcee8cd6..c50c6476ec5 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1693,8 +1693,14 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal( Group = C->getName(); } - return getContext().getWasmSection(Name, Kind, Group, - MCContext::GenericSectionID); + MCSectionWasm* Section = + getContext().getWasmSection(Name, Kind, Group, + MCContext::GenericSectionID); + + if (TM.Options.ThreadModel != ThreadModel::Single) + Section->setPassive(); + + return Section; } static MCSectionWasm *selectWasmSectionForGlobal( @@ -1723,7 +1729,12 @@ static MCSectionWasm *selectWasmSectionForGlobal( UniqueID = *NextUniqueID; (*NextUniqueID)++; } - return Ctx.getWasmSection(Name, Kind, Group, UniqueID); + + MCSectionWasm* Section = Ctx.getWasmSection(Name, Kind, Group, UniqueID); + if (Section->isWasmData() && TM.Options.ThreadModel != ThreadModel::Single) + Section->setPassive(); + + return Section; } MCSection *TargetLoweringObjectFileWasm::SelectSectionForGlobal( diff --git a/lib/MC/MCParser/WasmAsmParser.cpp b/lib/MC/MCParser/WasmAsmParser.cpp index 17d86aa0d64..a8a48d1cd69 100644 --- a/lib/MC/MCParser/WasmAsmParser.cpp +++ b/lib/MC/MCParser/WasmAsmParser.cpp @@ -81,13 +81,53 @@ public: return false; } + bool parseSectionFlags(StringRef FlagStr, bool &Passive) { + SmallVector Flags; + // If there are no flags, keep Flags empty + FlagStr.split(Flags, ",", -1, false); + for (auto &Flag : Flags) { + if (Flag == "passive") + Passive = true; + else + return error("Expected section flags, instead got: ", Lexer->getTok()); + } + return false; + } + bool parseSectionDirective(StringRef, SMLoc) { StringRef Name; if (Parser->parseIdentifier(Name)) return TokError("expected identifier in directive"); - // FIXME: currently requiring this very fixed format. - if (expect(AsmToken::Comma, ",") || expect(AsmToken::String, "string") || - expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") || + + if (expect(AsmToken::Comma, ",")) + return true; + + if (Lexer->isNot(AsmToken::String)) + return error("expected string in directive, instead got: ", Lexer->getTok()); + + SectionKind Kind = StringSwitch(Name) + .StartsWith(".data", SectionKind::getData()) + .StartsWith(".rodata", SectionKind::getReadOnly()) + .StartsWith(".text", SectionKind::getText()) + .StartsWith(".custom_section", SectionKind::getMetadata()); + + MCSectionWasm* Section = getContext().getWasmSection(Name, Kind); + + // Update section flags if present in this .section directive + bool Passive = false; + if (parseSectionFlags(getTok().getStringContents(), Passive)) + return true; + + if (Passive) { + if (!Section->isWasmData()) + return Parser->Error(getTok().getLoc(), + "Only data sections can be passive"); + Section->setPassive(); + } + + Lex(); + + if (expect(AsmToken::Comma, ",") || expect(AsmToken::At, "@") || expect(AsmToken::EndOfStatement, "eol")) return true; // This is done automatically by the assembler for text sections currently, diff --git a/lib/MC/MCSectionWasm.cpp b/lib/MC/MCSectionWasm.cpp index 164ded9a1f8..8633c10a73f 100644 --- a/lib/MC/MCSectionWasm.cpp +++ b/lib/MC/MCSectionWasm.cpp @@ -62,7 +62,8 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, printName(OS, getSectionName()); OS << ",\""; - // TODO: Print section flags. + if (IsPassive) + OS << "passive"; OS << '"'; diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index 600928c05bc..10f16ba3c8f 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -106,9 +106,10 @@ struct WasmSignatureDenseMapInfo { struct WasmDataSegment { MCSectionWasm *Section; StringRef Name; + uint32_t InitFlags; uint32_t Offset; uint32_t Alignment; - uint32_t Flags; + uint32_t LinkerFlags; SmallVector Data; }; @@ -899,10 +900,14 @@ void WasmObjectWriter::writeDataSection() { encodeULEB128(DataSegments.size(), W.OS); // count for (const WasmDataSegment &Segment : DataSegments) { - encodeULEB128(0, W.OS); // memory index - W.OS << char(wasm::WASM_OPCODE_I32_CONST); - encodeSLEB128(Segment.Offset, W.OS); // offset - W.OS << char(wasm::WASM_OPCODE_END); + encodeULEB128(Segment.InitFlags, W.OS); // flags + if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) + encodeULEB128(0, W.OS); // memory index + if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) { + W.OS << char(wasm::WASM_OPCODE_I32_CONST); + encodeSLEB128(Segment.Offset, W.OS); // offset + W.OS << char(wasm::WASM_OPCODE_END); + } encodeULEB128(Segment.Data.size(), W.OS); // size Segment.Section->setSectionOffset(W.OS.tell() - Section.ContentsOffset); W.OS << Segment.Data; // data @@ -1013,7 +1018,7 @@ void WasmObjectWriter::writeLinkingMetaDataSection( for (const WasmDataSegment &Segment : DataSegments) { writeString(Segment.Name); encodeULEB128(Segment.Alignment, W.OS); - encodeULEB128(Segment.Flags, W.OS); + encodeULEB128(Segment.LinkerFlags, W.OS); } endSection(SubSection); } @@ -1253,11 +1258,12 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, DataSegments.emplace_back(); WasmDataSegment &Segment = DataSegments.back(); Segment.Name = SectionName; + Segment.InitFlags = Section.getPassive() ? wasm::WASM_SEGMENT_IS_PASSIVE : 0; Segment.Offset = DataSize; Segment.Section = &Section; addData(Segment.Data, Section); Segment.Alignment = Log2_32(Section.getAlignment()); - Segment.Flags = 0; + Segment.LinkerFlags = 0; DataSize += Segment.Data.size(); Section.setSegmentIndex(SegmentIndex); diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp index e5b6a9b6e35..5a41ca3a89f 100644 --- a/lib/Object/WasmObjectFile.cpp +++ b/lib/Object/WasmObjectFile.cpp @@ -421,7 +421,7 @@ Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) { for (uint32_t I = 0; I < Count; I++) { DataSegments[I].Data.Name = readString(Ctx); DataSegments[I].Data.Alignment = readVaruint32(Ctx); - DataSegments[I].Data.Flags = readVaruint32(Ctx); + DataSegments[I].Data.LinkerFlags = readVaruint32(Ctx); } break; } @@ -1164,9 +1164,16 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) { DataSegments.reserve(Count); while (Count--) { WasmSegment Segment; - Segment.Data.MemoryIndex = readVaruint32(Ctx); - if (Error Err = readInitExpr(Segment.Data.Offset, Ctx)) - return Err; + Segment.Data.InitFlags = readVaruint32(Ctx); + Segment.Data.MemoryIndex = (Segment.Data.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) + ? readVaruint32(Ctx) : 0; + if ((Segment.Data.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) { + if (Error Err = readInitExpr(Segment.Data.Offset, Ctx)) + return Err; + } else { + Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Data.Offset.Value.Int32 = 0; + } uint32_t Size = readVaruint32(Ctx); if (Size > (size_t)(Ctx.End - Ctx.Ptr)) return make_error("Invalid segment size", @@ -1175,7 +1182,7 @@ Error WasmObjectFile::parseDataSection(ReadContext &Ctx) { // The rest of these Data fields are set later, when reading in the linking // metadata section. Segment.Data.Alignment = 0; - Segment.Data.Flags = 0; + Segment.Data.LinkerFlags = 0; Segment.Data.Comdat = UINT32_MAX; Segment.SectionOffset = Ctx.Ptr - Ctx.Start; Ctx.Ptr += Size; diff --git a/lib/ObjectYAML/WasmYAML.cpp b/lib/ObjectYAML/WasmYAML.cpp index def4d58a101..1865dcf7aa6 100644 --- a/lib/ObjectYAML/WasmYAML.cpp +++ b/lib/ObjectYAML/WasmYAML.cpp @@ -403,8 +403,18 @@ void MappingTraits::mapping(IO &IO, void MappingTraits::mapping( IO &IO, WasmYAML::DataSegment &Segment) { IO.mapOptional("SectionOffset", Segment.SectionOffset); - IO.mapRequired("MemoryIndex", Segment.MemoryIndex); - IO.mapRequired("Offset", Segment.Offset); + IO.mapRequired("InitFlags", Segment.InitFlags); + if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) { + IO.mapRequired("MemoryIndex", Segment.MemoryIndex); + } else { + Segment.MemoryIndex = 0; + } + if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) { + IO.mapRequired("Offset", Segment.Offset); + } else { + Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Value.Int32 = 0; + } IO.mapRequired("Content", Segment.Content); } diff --git a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 563c7cc203d..18ec2c273ec 100644 --- a/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -39,6 +39,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; #define DEBUG_TYPE "asm-printer" diff --git a/test/CodeGen/WebAssembly/global.ll b/test/CodeGen/WebAssembly/global.ll index 4e8f75e8d32..d7dd6f66b00 100644 --- a/test/CodeGen/WebAssembly/global.ll +++ b/test/CodeGen/WebAssembly/global.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s +; RUN: llc < %s -thread-model=single -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes=CHECK,SINGLE +; RUN: llc < %s -thread-model=posix -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefixes=CHECK,THREADS ; Test that globals assemble as expected. @@ -191,7 +192,8 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) { ; Constant global. ; CHECK: .type rom,@object{{$}} -; CHECK: .section .rodata.rom, +; SINGLE: .section .rodata.rom,"" +; THREADS: .section .rodata.rom,"passive" ; CHECK: .globl rom{{$}} ; CHECK: .p2align 4{{$}} ; CHECK: rom: @@ -204,7 +206,8 @@ define i8* @call_memcpy(i8* %p, i8* nocapture readonly %q, i32 %n) { ; CHECK-NEXT: .skip 8 ; CHECK-NEXT: .size array, 8 ; CHECK: .type pointer_to_array,@object -; CHECK-NEXT: .section .rodata.pointer_to_array, +; SINGLE-NEXT: .section .rodata.pointer_to_array,"" +; THREADS-NEXT: .section .rodata.pointer_to_array,"passive" ; CHECK-NEXT: .globl pointer_to_array ; CHECK-NEXT: .p2align 2 ; CHECK-NEXT: pointer_to_array: diff --git a/test/CodeGen/WebAssembly/vtable.ll b/test/CodeGen/WebAssembly/vtable.ll index 6a0d902254d..5a6d89d4e54 100644 --- a/test/CodeGen/WebAssembly/vtable.ll +++ b/test/CodeGen/WebAssembly/vtable.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=TYPEINFONAME -; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=VTABLE -; RUN: llc < %s -asm-verbose=false -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=TYPEINFO +; RUN: llc < %s -asm-verbose=false -thread-model=single -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=TYPEINFONAME +; RUN: llc < %s -asm-verbose=false -thread-model=single -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=VTABLE +; RUN: llc < %s -asm-verbose=false -thread-model=single -wasm-disable-explicit-locals -wasm-keep-registers | FileCheck %s --check-prefix=TYPEINFO ; Test that simple vtables assemble as expected. ; diff --git a/test/MC/WebAssembly/bss.ll b/test/MC/WebAssembly/bss.ll index 1ab3ec1339b..a274982ed5b 100644 --- a/test/MC/WebAssembly/bss.ll +++ b/test/MC/WebAssembly/bss.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -12,25 +12,25 @@ target triple = "wasm32-unknown-unknown" ; CHECK: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - SectionOffset: 15 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 4 ; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - SectionOffset: 24 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 ; CHECK-NEXT: Content: '' ; CHECK-NEXT: - SectionOffset: 29 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 diff --git a/test/MC/WebAssembly/comdat.ll b/test/MC/WebAssembly/comdat.ll index 9b61930cc7e..9b1ac501dbf 100644 --- a/test/MC/WebAssembly/comdat.ll +++ b/test/MC/WebAssembly/comdat.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -68,7 +68,7 @@ define linkonce_odr i32 @sharedFn() #1 comdat($sharedComdat) { ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 diff --git a/test/MC/WebAssembly/debug-info.ll b/test/MC/WebAssembly/debug-info.ll index fe4a4cf6983..374f5b3528b 100644 --- a/test/MC/WebAssembly/debug-info.ll +++ b/test/MC/WebAssembly/debug-info.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -s -symbols | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | llvm-readobj -r -s -symbols | FileCheck %s ; CHECK: Format: WASM ; CHECK-NEXT:Arch: wasm32 diff --git a/test/MC/WebAssembly/explicit-sections.ll b/test/MC/WebAssembly/explicit-sections.ll index ab2bb163fff..7fa6d4b6017 100644 --- a/test/MC/WebAssembly/explicit-sections.ll +++ b/test/MC/WebAssembly/explicit-sections.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -13,20 +13,20 @@ target triple = "wasm32-unknown-unknown" ; CHECK: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '08000000' ; CHECK-NEXT: - SectionOffset: 15 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 ; CHECK-NEXT: Content: '01000000030000000700000000000000' ; CHECK-NEXT: - SectionOffset: 36 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 24 ; CHECK-NEXT: Content: '08000000' diff --git a/test/MC/WebAssembly/external-data.ll b/test/MC/WebAssembly/external-data.ll index 4f172a146a6..7598c920903 100644 --- a/test/MC/WebAssembly/external-data.ll +++ b/test/MC/WebAssembly/external-data.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -17,14 +17,14 @@ target triple = "wasm32-unknown-unknown" ; CHECK-NEXT: Offset: 0x00000013 ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '0700000000000000' ; CHECK-NEXT: - SectionOffset: 19 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 ; CHECK-NEXT: Content: '00000000' diff --git a/test/MC/WebAssembly/external-func-address.ll b/test/MC/WebAssembly/external-func-address.ll index 95e679ab65d..7ad4faa2701 100644 --- a/test/MC/WebAssembly/external-func-address.ll +++ b/test/MC/WebAssembly/external-func-address.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" diff --git a/test/MC/WebAssembly/global-ctor-dtor.ll b/test/MC/WebAssembly/global-ctor-dtor.ll index 89d519383fb..1405803dd8f 100644 --- a/test/MC/WebAssembly/global-ctor-dtor.ll +++ b/test/MC/WebAssembly/global-ctor-dtor.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -103,8 +103,8 @@ declare void @func3() ; CHECK-NEXT: - Type: DATA ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '01040000' diff --git a/test/MC/WebAssembly/init-flags.ll b/test/MC/WebAssembly/init-flags.ll new file mode 100644 index 00000000000..a5d2662436e --- /dev/null +++ b/test/MC/WebAssembly/init-flags.ll @@ -0,0 +1,25 @@ +; RUN: llc -filetype=obj %s -thread-model=single -o - | obj2yaml | FileCheck %s --check-prefix=SINGLE +; RUN: llc -filetype=obj %s -thread-model=posix -o - | obj2yaml | FileCheck %s --check-prefix=THREADS + +; Test that setting thread-model=posix causes data segments to be +; emitted as passive segments (i.e. have InitFlags set to 1). + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +@str = private unnamed_addr constant [7 x i8] c"Hello!\00", align 1 + +; SINGLE: - Type: DATA +; SINGLE-NEXT: Segments: +; SINGLE-NEXT: - SectionOffset: 6 +; SINGLE-NEXT: InitFlags: 0 +; SINGLE-NEXT: Offset: +; SINGLE-NEXT: Opcode: I32_CONST +; SINGLE-NEXT: Value: 0 +; SINGLE-NEXT: Content: 48656C6C6F2100 + +; THREADS: - Type: DATA +; THREADS-NEXT: Segments: +; THREADS-NEXT: - SectionOffset: 3 +; THREADS-NEXT: InitFlags: 1 +; THREADS-NEXT: Content: 48656C6C6F2100 diff --git a/test/MC/WebAssembly/reloc-data.ll b/test/MC/WebAssembly/reloc-data.ll index 2c4b206fe9f..c812939711f 100644 --- a/test/MC/WebAssembly/reloc-data.ll +++ b/test/MC/WebAssembly/reloc-data.ll @@ -1,4 +1,4 @@ -; RUN: llc -O0 -filetype=obj %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s +; RUN: llc -O0 -filetype=obj -thread-model=single %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s target triple = "wasm32-unknown-unknown" diff --git a/test/MC/WebAssembly/unnamed-data.ll b/test/MC/WebAssembly/unnamed-data.ll index 48d61d78c6f..2eb30c71f4a 100644 --- a/test/MC/WebAssembly/unnamed-data.ll +++ b/test/MC/WebAssembly/unnamed-data.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s +; RUN: llc -filetype=obj -thread-model=single %s -o - | obj2yaml | FileCheck %s target triple = "wasm32-unknown-unknown" @@ -19,26 +19,26 @@ target triple = "wasm32-unknown-unknown" ; CHECK-NEXT: Offset: 0x00000025 ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: 68656C6C6F00 ; CHECK-NEXT: - SectionOffset: 17 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 6 ; CHECK-NEXT: Content: 776F726C6400 ; CHECK-NEXT: - SectionOffset: 28 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 16 ; CHECK-NEXT: Content: '00000000' ; CHECK-NEXT: - SectionOffset: 37 -; CHECK-NEXT: MemoryIndex: 0 -; CHECK-NEXT: Offset: +; CHECK-NEXT: InitFlags: 0 +; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 24 ; CHECK-NEXT: Content: '06000000' diff --git a/test/MC/WebAssembly/weak-alias.ll b/test/MC/WebAssembly/weak-alias.ll index c02ca889222..fe8112ddacb 100644 --- a/test/MC/WebAssembly/weak-alias.ll +++ b/test/MC/WebAssembly/weak-alias.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj -wasm-keep-registers %s -o %t.o +; RUN: llc -filetype=obj -thread-model=single -wasm-keep-registers %s -o %t.o ; RUN: obj2yaml %t.o | FileCheck %s ; RUN: llvm-objdump -t %t.o | FileCheck --check-prefix=CHECK-SYMS %s @@ -119,19 +119,19 @@ entry: ; CHECK-NEXT: Offset: 0x00000018 ; CHECK-NEXT: Segments: ; CHECK-NEXT: - SectionOffset: 6 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 0 ; CHECK-NEXT: Content: '07000000' ; CHECK-NEXT: - SectionOffset: 15 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 8 ; CHECK-NEXT: Content: '01000000' ; CHECK-NEXT: - SectionOffset: 24 -; CHECK-NEXT: MemoryIndex: 0 +; CHECK-NEXT: InitFlags: 0 ; CHECK-NEXT: Offset: ; CHECK-NEXT: Opcode: I32_CONST ; CHECK-NEXT: Value: 16 diff --git a/test/ObjectYAML/wasm/data_section.yaml b/test/ObjectYAML/wasm/data_section.yaml index 2ebdf9c4d1c..fce4be16320 100644 --- a/test/ObjectYAML/wasm/data_section.yaml +++ b/test/ObjectYAML/wasm/data_section.yaml @@ -8,11 +8,19 @@ Sections: - Initial: 0x00000003 - Type: DATA Segments: - - MemoryIndex: 0 + - InitFlags: 0 Offset: Opcode: I32_CONST Value: 4 Content: '10001000' + - InitFlags: 1 + Content: '01010101' + - InitFlags: 2 + MemoryIndex: 0 + Offset: + Opcode: I32_CONST + Value: 8 + Content: '00110011' Relocations: - Type: R_WASM_MEMORY_ADDR_I32 Index: 0 @@ -49,10 +57,20 @@ Sections: # CHECK-NEXT: Offset: 0x00000006 # CHECK-NEXT: Addend: -6 # CHECK-NEXT: Segments: -# CHECK-NEXT: - SectionOffset: 6 -# CHECK-NEXT: MemoryIndex: 0 +# CHECK-NEXT: - SectionOffset: 6 +# CHECK-NEXT: InitFlags: 0 +# CHECK-NEXT: Offset: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 4 +# CHECK-NEXT: Content: '10001000' +# CHECK-NEXT: - SectionOffset: 12 +# CHECK-NEXT: InitFlags: 1 +# CHECK-NEXT: Content: '01010101' +# CHECK-NEXT: - SectionOffset: 22 +# CHECK-NEXT: InitFlags: 2 +# CHECK-NEXT: MemoryIndex: 0 # CHECK-NEXT: Offset: -# CHECK-NEXT: Opcode: I32_CONST -# CHECK-NEXT: Value: 4 -# CHECK-NEXT: Content: '10001000' +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 8 +# CHECK-NEXT: Content: '00110011' # CHECK-NEXT: - Type: CUSTOM diff --git a/test/ObjectYAML/wasm/linking_section.yaml b/test/ObjectYAML/wasm/linking_section.yaml index 69817f50970..39827410b0e 100644 --- a/test/ObjectYAML/wasm/linking_section.yaml +++ b/test/ObjectYAML/wasm/linking_section.yaml @@ -17,12 +17,12 @@ Sections: SigIndex: 0 - Type: DATA Segments: - - MemoryIndex: 0 + - InitFlags: 0 Offset: Opcode: I32_CONST Value: 4 Content: '10001000' - - MemoryIndex: 0 + - InitFlags: 0 Offset: Opcode: I32_CONST Value: 8 diff --git a/test/tools/llvm-nm/wasm/exports.yaml b/test/tools/llvm-nm/wasm/exports.yaml index 756e9c1e051..eddcbc22c1f 100644 --- a/test/tools/llvm-nm/wasm/exports.yaml +++ b/test/tools/llvm-nm/wasm/exports.yaml @@ -30,7 +30,7 @@ Sections: - Type: DATA Segments: - SectionOffset: 6 - MemoryIndex: 0 + InitFlags: 0 Offset: Opcode: I32_CONST Value: 0 diff --git a/test/tools/llvm-nm/wasm/local-symbols.ll b/test/tools/llvm-nm/wasm/local-symbols.ll index f7c0e837cc9..cc64f2e7f47 100644 --- a/test/tools/llvm-nm/wasm/local-symbols.ll +++ b/test/tools/llvm-nm/wasm/local-symbols.ll @@ -1,4 +1,4 @@ -; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown -o %t.o %s +; RUN: llc -filetype=obj -thread-model=single -mtriple=wasm32-unknown-unknown -o %t.o %s ; RUN: llvm-nm %t.o | FileCheck %s @foo = internal global i32 1, align 4 diff --git a/test/tools/llvm-nm/wasm/weak-symbols.yaml b/test/tools/llvm-nm/wasm/weak-symbols.yaml index 36711b17b98..a81559402dc 100644 --- a/test/tools/llvm-nm/wasm/weak-symbols.yaml +++ b/test/tools/llvm-nm/wasm/weak-symbols.yaml @@ -36,7 +36,7 @@ Sections: - Type: DATA Segments: - SectionOffset: 6 - MemoryIndex: 0 + InitFlags: 0 Offset: Opcode: I32_CONST Value: 0 diff --git a/test/tools/llvm-objdump/WebAssembly/relocations.test b/test/tools/llvm-objdump/WebAssembly/relocations.test index acf276e7ba7..d86e9392651 100644 --- a/test/tools/llvm-objdump/WebAssembly/relocations.test +++ b/test/tools/llvm-objdump/WebAssembly/relocations.test @@ -1,4 +1,4 @@ -; RUN: llc -mtriple=wasm32-unknown-unknown -filetype=obj %s -o - | llvm-objdump -r - | FileCheck %s +; RUN: llc -thread-model=single -mtriple=wasm32-unknown-unknown -filetype=obj %s -o - | llvm-objdump -r - | FileCheck %s @foo = external global i32, align 4 @bar = global i32* @foo, align 4 diff --git a/tools/obj2yaml/wasm2yaml.cpp b/tools/obj2yaml/wasm2yaml.cpp index 8e7f2fa641f..b6eef9cf9fb 100644 --- a/tools/obj2yaml/wasm2yaml.cpp +++ b/tools/obj2yaml/wasm2yaml.cpp @@ -93,7 +93,7 @@ WasmDumper::dumpCustomSection(const WasmSection &WasmSec) { SegmentInfo.Name = Segment.Data.Name; SegmentInfo.Index = SegmentIndex; SegmentInfo.Alignment = Segment.Data.Alignment; - SegmentInfo.Flags = Segment.Data.Flags; + SegmentInfo.Flags = Segment.Data.LinkerFlags; LinkingSec->SegmentInfos.push_back(SegmentInfo); } if (Segment.Data.Comdat != UINT32_MAX) { @@ -334,6 +334,7 @@ ErrorOr WasmDumper::dump() { for (const object::WasmSegment &Segment : Obj.dataSegments()) { WasmYAML::DataSegment Seg; Seg.SectionOffset = Segment.SectionOffset; + Seg.InitFlags = Segment.Data.InitFlags; Seg.MemoryIndex = Segment.Data.MemoryIndex; Seg.Offset = Segment.Data.Offset; Seg.Content = yaml::BinaryRef(Segment.Data.Content); diff --git a/tools/yaml2obj/yaml2wasm.cpp b/tools/yaml2obj/yaml2wasm.cpp index 3398ace3e1e..fcbcb8a40d5 100644 --- a/tools/yaml2obj/yaml2wasm.cpp +++ b/tools/yaml2obj/yaml2wasm.cpp @@ -487,8 +487,11 @@ int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section) { encodeULEB128(Section.Segments.size(), OS); for (auto &Segment : Section.Segments) { - encodeULEB128(Segment.MemoryIndex, OS); - writeInitExpr(Segment.Offset, OS); + encodeULEB128(Segment.InitFlags, OS); + if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX) + encodeULEB128(Segment.MemoryIndex, OS); + if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0) + writeInitExpr(Segment.Offset, OS); encodeULEB128(Segment.Content.binary_size(), OS); Segment.Content.writeAsBinary(OS); } -- 2.40.0