};
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<uint8_t> 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
};
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,
// 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)
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; }
};
};
struct DataSegment {
- uint32_t MemoryIndex;
uint32_t SectionOffset;
+ uint32_t InitFlags;
+ uint32_t MemoryIndex;
wasm::WasmInitExpr Offset;
yaml::BinaryRef Content;
};
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(
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(
return false;
}
+ bool parseSectionFlags(StringRef FlagStr, bool &Passive) {
+ SmallVector<StringRef, 2> 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<SectionKind>(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,
printName(OS, getSectionName());
OS << ",\"";
- // TODO: Print section flags.
+ if (IsPassive)
+ OS << "passive";
OS << '"';
struct WasmDataSegment {
MCSectionWasm *Section;
StringRef Name;
+ uint32_t InitFlags;
uint32_t Offset;
uint32_t Alignment;
- uint32_t Flags;
+ uint32_t LinkerFlags;
SmallVector<char, 4> Data;
};
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
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);
}
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);
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;
}
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<GenericBinaryError>("Invalid segment size",
// 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;
void MappingTraits<WasmYAML::DataSegment>::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);
}
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
+
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
-; 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.
; 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:
; 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:
-; 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.
;
-; 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"
; 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
-; 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"
; 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
-; 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
-; 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"
; 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'
-; 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"
; 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'
-; 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"
-; 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"
; 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'
--- /dev/null
+; 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
-; 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"
-; 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"
; 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'
-; 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
; 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
- 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
# 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
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
- Type: DATA
Segments:
- SectionOffset: 6
- MemoryIndex: 0
+ InitFlags: 0
Offset:
Opcode: I32_CONST
Value: 0
-; 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
- Type: DATA
Segments:
- SectionOffset: 6
- MemoryIndex: 0
+ InitFlags: 0
Offset:
Opcode: I32_CONST
Value: 0
-; 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
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) {
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);
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);
}