summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2017-12-06 23:57:11 +0000
committerDan Gohman <dan433584@gmail.com>2017-12-06 23:57:11 +0000
commit96d22e12a2ef934283286e2ed1e19a0420476be4 (patch)
tree1f8bafab14ba25665933988f57acd6bceeb49e59
parenta97bd9a7d3bf98ce7af9cc918212470583dd7f87 (diff)
downloadbcm5719-llvm-96d22e12a2ef934283286e2ed1e19a0420476be4.tar.gz
bcm5719-llvm-96d22e12a2ef934283286e2ed1e19a0420476be4.zip
[WebAssembly] Import the linear memory and function table.
Instead of having .o files contain linear-memory and function table definitions, use imports. This is more consistent with the stack pointer being imported, and it's consistent with the linker being the one to decide whether linear memory and function table are imported or defined in the linked output. This implements tool-conventions #23. Differential Revision: https://reviews.llvm.org/D40875 llvm-svn: 319989
-rw-r--r--llvm/lib/MC/WasmObjectWriter.cpp82
-rw-r--r--llvm/test/MC/WebAssembly/external-func-address.ll6
-rw-r--r--llvm/test/MC/WebAssembly/func-address.ll2
-rw-r--r--llvm/test/MC/WebAssembly/init-fini-array.ll20
-rw-r--r--llvm/test/MC/WebAssembly/reloc-code.ll2
-rw-r--r--llvm/test/MC/WebAssembly/reloc-data.ll2
-rw-r--r--llvm/test/MC/WebAssembly/sections.ll11
-rw-r--r--llvm/test/MC/WebAssembly/weak-alias.ll22
-rw-r--r--llvm/test/MC/WebAssembly/weak.ll6
9 files changed, 81 insertions, 72 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 351927d628a..7c50f437cfa 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -270,10 +270,9 @@ private:
}
void writeTypeSection(ArrayRef<WasmFunctionType> FunctionTypes);
- void writeImportSection(ArrayRef<WasmImport> Imports);
+ void writeImportSection(ArrayRef<WasmImport> Imports, uint32_t DataSize,
+ uint32_t NumElements);
void writeFunctionSection(ArrayRef<WasmFunction> Functions);
- void writeTableSection(uint32_t NumElements);
- void writeMemorySection(uint32_t DataSize);
void writeGlobalSection();
void writeExportSection(ArrayRef<WasmExport> Exports);
void writeElemSection(ArrayRef<uint32_t> TableElems);
@@ -661,10 +660,14 @@ void WasmObjectWriter::writeTypeSection(
endSection(Section);
}
-void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
+void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports,
+ uint32_t DataSize,
+ uint32_t NumElements) {
if (Imports.empty())
return;
+ uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;
+
SectionBookkeeping Section;
startSection(Section, wasm::WASM_SEC_IMPORT);
@@ -683,6 +686,15 @@ void WasmObjectWriter::writeImportSection(ArrayRef<WasmImport> Imports) {
encodeSLEB128(int32_t(Import.Type), getStream());
encodeULEB128(int32_t(Import.IsMutable), getStream());
break;
+ case wasm::WASM_EXTERNAL_MEMORY:
+ encodeULEB128(0, getStream()); // flags
+ encodeULEB128(NumPages, getStream()); // initial
+ break;
+ case wasm::WASM_EXTERNAL_TABLE:
+ encodeSLEB128(int32_t(Import.Type), getStream());
+ encodeULEB128(0, getStream()); // flags
+ encodeULEB128(NumElements, getStream()); // initial
+ break;
default:
llvm_unreachable("unsupported import kind");
}
@@ -705,39 +717,6 @@ void WasmObjectWriter::writeFunctionSection(ArrayRef<WasmFunction> Functions) {
endSection(Section);
}
-void WasmObjectWriter::writeTableSection(uint32_t NumElements) {
- // For now, always emit the table section, since indirect calls are not
- // valid without it. In the future, we could perhaps be more clever and omit
- // it if there are no indirect calls.
-
- SectionBookkeeping Section;
- startSection(Section, wasm::WASM_SEC_TABLE);
-
- encodeULEB128(1, getStream()); // The number of tables.
- // Fixed to 1 for now.
- encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream()); // Type of table
- encodeULEB128(0, getStream()); // flags
- encodeULEB128(NumElements, getStream()); // initial
-
- endSection(Section);
-}
-
-void WasmObjectWriter::writeMemorySection(uint32_t DataSize) {
- // For now, always emit the memory section, since loads and stores are not
- // valid without it. In the future, we could perhaps be more clever and omit
- // it if there are no loads or stores.
- SectionBookkeeping Section;
- uint32_t NumPages = (DataSize + wasm::WasmPageSize - 1) / wasm::WasmPageSize;
-
- startSection(Section, wasm::WASM_SEC_MEMORY);
- encodeULEB128(1, getStream()); // number of memory spaces
-
- encodeULEB128(0, getStream()); // flags
- encodeULEB128(NumPages, getStream()); // initial
-
- endSection(Section);
-}
-
void WasmObjectWriter::writeGlobalSection() {
if (Globals.empty())
return;
@@ -1085,6 +1064,29 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
}
}
+ // For now, always emit the memory import, since loads and stores are not
+ // valid without it. In the future, we could perhaps be more clever and omit
+ // it if there are no loads or stores.
+ MCSymbolWasm *MemorySym =
+ cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory"));
+ WasmImport MemImport;
+ MemImport.ModuleName = MemorySym->getModuleName();
+ MemImport.FieldName = MemorySym->getName();
+ MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
+ Imports.push_back(MemImport);
+
+ // For now, always emit the table section, since indirect calls are not
+ // valid without it. In the future, we could perhaps be more clever and omit
+ // it if there are no indirect calls.
+ MCSymbolWasm *TableSym =
+ cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table"));
+ WasmImport TableImport;
+ TableImport.ModuleName = TableSym->getModuleName();
+ TableImport.FieldName = TableSym->getName();
+ TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
+ TableImport.Type = wasm::WASM_TYPE_ANYFUNC;
+ Imports.push_back(TableImport);
+
// Populate FunctionTypeIndices and Imports.
for (const MCSymbol &S : Asm.symbols()) {
const auto &WS = static_cast<const MCSymbolWasm &>(S);
@@ -1295,10 +1297,10 @@ void WasmObjectWriter::writeObject(MCAssembler &Asm,
writeHeader(Asm);
writeTypeSection(FunctionTypes);
- writeImportSection(Imports);
+ writeImportSection(Imports, DataSize, TableElems.size());
writeFunctionSection(Functions);
- writeTableSection(TableElems.size());
- writeMemorySection(DataSize);
+ // Skip the "table" section; we import the table instead.
+ // Skip the "memory" section; we import the memory instead.
writeGlobalSection();
writeExportSection(Exports);
// TODO: Start Section
diff --git a/llvm/test/MC/WebAssembly/external-func-address.ll b/llvm/test/MC/WebAssembly/external-func-address.ll
index 53da9805f98..9386d945ccd 100644
--- a/llvm/test/MC/WebAssembly/external-func-address.ll
+++ b/llvm/test/MC/WebAssembly/external-func-address.ll
@@ -17,7 +17,11 @@ declare void @f1(i32) #1
; CHECK-NEXT: - I32
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
-; CHECK-NEXT: - Module: env
+; CHECK: - Module: env
+; CHECK-NEXT: Field: __linear_memory
+; CHECK: - Module: env
+; CHECK-NEXT: Field: __indirect_function_table
+; CHECK: - Module: env
; CHECK-NEXT: Field: f1
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
diff --git a/llvm/test/MC/WebAssembly/func-address.ll b/llvm/test/MC/WebAssembly/func-address.ll
index 15c09e0ebd8..16d38e1ebf2 100644
--- a/llvm/test/MC/WebAssembly/func-address.ll
+++ b/llvm/test/MC/WebAssembly/func-address.ll
@@ -28,7 +28,7 @@ entry:
; CHECK: }
; CHECK: Relocations [
-; CHECK: Section (8) CODE {
+; CHECK: Section (6) CODE {
; CHECK: Relocation {
; CHECK: Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
; CHECK: Offset: 0x4
diff --git a/llvm/test/MC/WebAssembly/init-fini-array.ll b/llvm/test/MC/WebAssembly/init-fini-array.ll
index 5cd32ff9bf5..b7a1826bdc4 100644
--- a/llvm/test/MC/WebAssembly/init-fini-array.ll
+++ b/llvm/test/MC/WebAssembly/init-fini-array.ll
@@ -14,6 +14,18 @@ declare void @func2()
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __linear_memory
+; CHECK-NEXT: Kind: MEMORY
+; CHECK-NEXT: Memory:
+; CHECK-NEXT: Initial: 0x00000001
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __indirect_function_table
+; CHECK-NEXT: Kind: TABLE
+; CHECK-NEXT: Table:
+; CHECK-NEXT: ElemType: ANYFUNC
+; CHECK-NEXT: Limits:
+; CHECK-NEXT: Initial: 0x00000002
+; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: func1
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
@@ -21,14 +33,6 @@ declare void @func2()
; CHECK-NEXT: Field: func2
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
-; CHECK-NEXT: - Type: TABLE
-; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
-; CHECK-NEXT: Limits:
-; CHECK-NEXT: Initial: 0x00000002
-; CHECK-NEXT: - Type: MEMORY
-; CHECK-NEXT: Memories:
-; CHECK-NEXT: - Initial: 0x00000001
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
diff --git a/llvm/test/MC/WebAssembly/reloc-code.ll b/llvm/test/MC/WebAssembly/reloc-code.ll
index f007b63ca83..e9aff890cff 100644
--- a/llvm/test/MC/WebAssembly/reloc-code.ll
+++ b/llvm/test/MC/WebAssembly/reloc-code.ll
@@ -22,7 +22,7 @@ entry:
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (8) CODE {
+; CHECK-NEXT: Section (6) CODE {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_LEB (3)
; CHECK-NEXT: Offset: 0x9
diff --git a/llvm/test/MC/WebAssembly/reloc-data.ll b/llvm/test/MC/WebAssembly/reloc-data.ll
index 519df036751..ca78d8b158f 100644
--- a/llvm/test/MC/WebAssembly/reloc-data.ll
+++ b/llvm/test/MC/WebAssembly/reloc-data.ll
@@ -10,7 +10,7 @@
; CHECK: Format: WASM
; CHECK: Relocations [
-; CHECK-NEXT: Section (6) DATA {
+; CHECK-NEXT: Section (4) DATA {
; CHECK-NEXT: Relocation {
; CHECK-NEXT: Type: R_WEBASSEMBLY_MEMORY_ADDR_I32 (5)
; CHECK-NEXT: Offset: 0x13
diff --git a/llvm/test/MC/WebAssembly/sections.ll b/llvm/test/MC/WebAssembly/sections.ll
index 85bf0818509..14c9cc6ab07 100644
--- a/llvm/test/MC/WebAssembly/sections.ll
+++ b/llvm/test/MC/WebAssembly/sections.ll
@@ -28,17 +28,6 @@ entry:
; CHECK: Type: FUNCTION (0x3)
; CHECK: }
; CHECK: Section {
-; CHECK: Type: TABLE (0x4)
-; CHECK: }
-; CHECK: Section {
-; CHECK: Type: MEMORY (0x5)
-; CHECK: Memories [
-; CHECK: Memory {
-; CHECK: InitialPages: 1
-; CHECK: }
-; CHECK: ]
-; CHECK: }
-; CHECK: Section {
; CHECK: Type: GLOBAL (0x6)
; CHECK: }
; CHECK: Section {
diff --git a/llvm/test/MC/WebAssembly/weak-alias.ll b/llvm/test/MC/WebAssembly/weak-alias.ll
index 4129870ce23..5c85fc09b03 100644
--- a/llvm/test/MC/WebAssembly/weak-alias.ll
+++ b/llvm/test/MC/WebAssembly/weak-alias.ll
@@ -29,16 +29,22 @@ entry:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
+; CHECK-NEXT: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __linear_memory
+; CHECK-NEXT: Kind: MEMORY
+; CHECK-NEXT: Memory:
+; CHECK-NEXT: Initial: 0x00000001
+; CHECK-NEXT: - Module: env
+; CHECK-NEXT: Field: __indirect_function_table
+; CHECK-NEXT: Kind: TABLE
+; CHECK-NEXT: Table:
+; CHECK-NEXT: ElemType: ANYFUNC
+; CHECK-NEXT: Limits:
+; CHECK-NEXT: Initial: 0x00000000
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 0, 0 ]
-; CHECK-NEXT: - Type: TABLE
-; CHECK-NEXT: Tables:
-; CHECK-NEXT: - ElemType: ANYFUNC
-; CHECK-NEXT: Limits:
-; CHECK-NEXT: Initial: 0x00000000
-; CHECK-NEXT: - Type: MEMORY
-; CHECK-NEXT: Memories:
-; CHECK-NEXT: - Initial: 0x00000001
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
diff --git a/llvm/test/MC/WebAssembly/weak.ll b/llvm/test/MC/WebAssembly/weak.ll
index f7353569024..af177b53595 100644
--- a/llvm/test/MC/WebAssembly/weak.ll
+++ b/llvm/test/MC/WebAssembly/weak.ll
@@ -12,7 +12,11 @@ entry:
; CHECK: - Type: IMPORT
; CHECK-NEXT: Imports:
-; CHECK-NEXT: - Module: env
+; CHECK: - Module: env
+; CHECK-NEXT: Field: __linear_memory
+; CHECK: - Module: env
+; CHECK-NEXT: Field: __indirect_function_table
+; CHECK: - Module: env
; CHECK-NEXT: Field: weak_external_data
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: GlobalType: I32
OpenPOWER on IntegriCloud