llvm.org GIT mirror llvm / 65e284e
[WebAssembly] Improve libObject support for wasm imports and exports Previously we had only supported the importing and exporting of functions and globals. Also, add usefull overload of getWasmSymbol() and getNumberOfSymbols() in support of lld port. Differential Revision: https://reviews.llvm.org/D33011 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302601 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 2 years ago
9 changed file(s) with 192 addition(s) and 97 deletion(s). Raw diff Collapse all Expand all
6666 WasmObjectFile(MemoryBufferRef Object, Error &Err);
6767
6868 const wasm::WasmObjectHeader &getHeader() const;
69 const WasmSymbol &getWasmSymbol(DataRefImpl Symb) const;
69 const WasmSymbol &getWasmSymbol(const DataRefImpl &Symb) const;
70 const WasmSymbol &getWasmSymbol(const SymbolRef &Symbol) const;
7071 const WasmSection &getWasmSection(const SectionRef &Section) const;
7172 const wasm::WasmRelocation &getWasmRelocation(const RelocationRef& Ref) const;
7273
7980 const std::vector& memories() const { return Memories; }
8081 const std::vector& globals() const { return Globals; }
8182 const std::vector& exports() const { return Exports; }
83
84 uint32_t getNumberOfSymbols() const {
85 return Symbols.size();
86 }
8287
8388 const std::vector& elements() const {
8489 return ElemSegments;
3333 yaml::Hex32 Version;
3434 };
3535
36 struct Limits {
37 yaml::Hex32 Flags;
38 yaml::Hex32 Initial;
39 yaml::Hex32 Maximum;
40 };
41
42 struct Table {
43 TableType ElemType;
44 Limits TableLimits;
45 };
46
47 struct Export {
48 StringRef Name;
49 ExportKind Kind;
50 uint32_t Index;
51 };
52
53 struct ElemSegment {
54 uint32_t TableIndex;
55 wasm::WasmInitExpr Offset;
56 std::vector Functions;
57 };
58
59 struct Global {
60 ValueType Type;
61 bool Mutable;
62 wasm::WasmInitExpr InitExpr;
63 };
64
3665 struct Import {
3766 StringRef Module;
3867 StringRef Field;
3968 ExportKind Kind;
4069 union {
4170 uint32_t SigIndex;
42 ValueType GlobalType;
71 Global Global;
72 Table Table;
73 Limits Memory;
4374 };
44 bool GlobalMutable;
45 };
46
47 struct Limits {
48 yaml::Hex32 Flags;
49 yaml::Hex32 Initial;
50 yaml::Hex32 Maximum;
51 };
52
53 struct Table {
54 TableType ElemType;
55 Limits TableLimits;
56 };
57
58 struct Export {
59 StringRef Name;
60 ExportKind Kind;
61 uint32_t Index;
62 };
63
64 struct ElemSegment {
65 uint32_t TableIndex;
66 wasm::WasmInitExpr Offset;
67 std::vector Functions;
68 };
69
70 struct Global {
71 ValueType Type;
72 bool Mutable;
73 wasm::WasmInitExpr InitExpr;
7475 };
7576
7677 struct LocalDecl {
3434 struct WasmSignature {
3535 std::vector ParamTypes;
3636 int32_t ReturnType;
37 };
38
39 struct WasmImport {
40 StringRef Module;
41 StringRef Field;
42 uint32_t Kind;
43 union {
44 uint32_t SigIndex;
45 int32_t GlobalType;
46 };
47 bool GlobalMutable;
4837 };
4938
5039 struct WasmExport {
7968 int32_t Type;
8069 bool Mutable;
8170 WasmInitExpr InitExpr;
71 };
72
73 struct WasmImport {
74 StringRef Module;
75 StringRef Field;
76 uint32_t Kind;
77 union {
78 uint32_t SigIndex;
79 WasmGlobal Global;
80 WasmTable Table;
81 WasmLimits Memory;
82 };
8283 };
8384
8485 struct WasmLocalDecl {
165165 if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
166166 Result.Maximum = readVaruint32(Ptr);
167167 return Result;
168 }
169
170 static wasm::WasmTable readTable(const uint8_t *&Ptr) {
171 wasm::WasmTable Table;
172 Table.ElemType = readVarint7(Ptr);
173 Table.Limits = readLimits(Ptr);
174 return Table;
168175 }
169176
170177 static Error readSection(WasmSection &Section, const uint8_t *&Ptr,
396403 Sections.size(), i);
397404 break;
398405 case wasm::WASM_EXTERNAL_GLOBAL:
399 Im.GlobalType = readVarint7(Ptr);
400 Im.GlobalMutable = readVaruint1(Ptr);
406 Im.Global.Type = readVarint7(Ptr);
407 Im.Global.Mutable = readVaruint1(Ptr);
401408 Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
402409 Sections.size(), i);
403410 break;
411 case wasm::WASM_EXTERNAL_MEMORY:
412 Im.Memory = readLimits(Ptr);
413 break;
414 case wasm::WASM_EXTERNAL_TABLE:
415 Im.Table = readTable(Ptr);
416 if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC) {
417 return make_error("Invalid table element type",
418 object_error::parse_failed);
419 }
420 break;
404421 default:
405 // TODO(sbc): Handle other kinds of imports
406422 return make_error(
407423 "Unexpected import kind", object_error::parse_failed);
408424 }
430446 uint32_t Count = readVaruint32(Ptr);
431447 Tables.reserve(Count);
432448 while (Count--) {
433 wasm::WasmTable Table;
434 Table.ElemType = readVarint7(Ptr);
435 if (Table.ElemType != wasm::WASM_TYPE_ANYFUNC) {
449 Tables.push_back(readTable(Ptr));
450 if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) {
436451 return make_error("Invalid table element type",
437452 object_error::parse_failed);
438453 }
439 Table.Limits = readLimits(Ptr);
440 Tables.push_back(Table);
441454 }
442455 if (Ptr != End)
443456 return make_error("Table section ended prematurely",
492505 Symbols.emplace_back(Ex.Name, WasmSymbol::SymbolType::GLOBAL_EXPORT,
493506 Sections.size(), i);
494507 break;
508 case wasm::WASM_EXTERNAL_MEMORY:
509 case wasm::WASM_EXTERNAL_TABLE:
510 break;
495511 default:
496 // TODO(sbc): Handle other kinds of exports
497512 return make_error(
498513 "Unexpected export kind", object_error::parse_failed);
499514 }
637652 return BasicSymbolRef(Ref, this);
638653 }
639654
640 const WasmSymbol &WasmObjectFile::getWasmSymbol(DataRefImpl Symb) const {
655 const WasmSymbol &WasmObjectFile::getWasmSymbol(const DataRefImpl &Symb) const {
641656 return Symbols[Symb.d.a];
657 }
658
659 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
660 return getWasmSymbol(Symb.getRawDataRefImpl());
642661 }
643662
644663 Expected WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
264264 if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
265265 IO.mapRequired("SigIndex", Import.SigIndex);
266266 } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
267 IO.mapRequired("GlobalType", Import.GlobalType);
268 IO.mapRequired("GlobalMutable", Import.GlobalMutable);
267 IO.mapRequired("GlobalType", Import.Global.Type);
268 IO.mapRequired("GlobalMutable", Import.Global.Mutable);
269 } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) {
270 IO.mapRequired("Table", Import.Table);
271 } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY ) {
272 IO.mapRequired("Memory", Import.Memory);
269273 } else {
270274 llvm_unreachable("unhandled import type");
271275 }
44 Sections:
55 - Type: EXPORT
66 Exports:
7 - Name: foo
8 Kind: FUNCTION
9 Index: 0
10 - Name: bar
7 - Name: function_export
118 Kind: FUNCTION
129 Index: 1
10 - Name: global_export
11 Kind: GLOBAL
12 Index: 1
13 - Name: memory_export
14 Kind: MEMORY
15 Index: 0
16 - Name: table_export
17 Kind: TABLE
18 Index: 0
1319 ...
1420 # CHECK: --- !WASM
1521 # CHECK: FileHeader:
1723 # CHECK: Sections:
1824 # CHECK: - Type: EXPORT
1925 # CHECK: Exports:
20 # CHECK: - Name: foo
21 # CHECK: Kind: FUNCTION
22 # CHECK: Index: 0
23 # CHECK: - Name: bar
26 # CHECK: - Name: function_export
2427 # CHECK: Kind: FUNCTION
2528 # CHECK: Index: 1
29 # CHECK: - Name: global_export
30 # CHECK: Kind: GLOBAL
31 # CHECK: Index: 1
32 # CHECK: - Name: memory_export
33 # CHECK: Kind: MEMORY
34 # CHECK: Index: 0
35 # CHECK: - Name: table_export
36 # CHECK: Kind: TABLE
37 # CHECK: Index: 0
2638 # CHECK: ...
88 ParamTypes:
99 - I32
1010 - Type: IMPORT
11 Imports:
11 Imports:
1212 - Module: foo
13 Field: bar
13 Field: imported_function
1414 Kind: FUNCTION
1515 SigIndex: 0
1616 - Module: fiz
17 Field: baz
17 Field: imported_global
1818 Kind: GLOBAL
1919 GlobalType: I32
2020 GlobalMutable: false
21 - Type: FUNCTION
22 FunctionTypes:
23 - 0
21 - Module: foo
22 Field: imported_memory
23 Kind: MEMORY
24 Memory:
25 Flags: 0x00000001
26 Initial: 0x00000010
27 Maximum: 0x00000011
28 - Module: foo
29 Field: imported_table
30 Kind: TABLE
31 Table:
32 ElemType: ANYFUNC
33 Limits:
34 Flags: 0x00000001
35 Initial: 0x00000020
36 Maximum: 0x00000022
2437 ...
2538 # CHECK: --- !WASM
2639 # CHECK: FileHeader:
2942 # CHECK: - Type: IMPORT
3043 # CHECK: Imports:
3144 # CHECK: - Module: foo
32 # CHECK: Field: bar
45 # CHECK: Field: imported_function
3346 # CHECK: Kind: FUNCTION
3447 # CHECK: SigIndex: 0
3548 # CHECK: - Module: fiz
36 # CHECK: Field: baz
49 # CHECK: Field: imported_global
3750 # CHECK: Kind: GLOBAL
3851 # CHECK: GlobalType: I32
3952 # CHECK: GlobalMutable: false
53 # CHECK: - Module: foo
54 # CHECK: Field: imported_memory
55 # CHECK: Kind: MEMORY
56 # CHECK: Memory:
57 # CHECK: Flags: 0x00000001
58 # CHECK: Initial: 0x00000010
59 # CHECK: Maximum: 0x00000011
60 # CHECK: - Module: foo
61 # CHECK: Field: imported_table
62 # CHECK: Kind: TABLE
63 # CHECK: Table:
64 # CHECK: ElemType: ANYFUNC
65 # CHECK: Limits:
66 # CHECK: Flags: 0x00000001
67 # CHECK: Initial: 0x00000020
68 # CHECK: Maximum: 0x00000022
4069 # CHECK: ...
2323 WasmDumper(const object::WasmObjectFile &O) : Obj(O) {}
2424 ErrorOr dump();
2525 };
26
27 WasmYAML::Table make_table(const wasm::WasmTable &Table) {
28 WasmYAML::Table T;
29 T.ElemType = Table.ElemType;
30 T.TableLimits.Flags = Table.Limits.Flags;
31 T.TableLimits.Initial = Table.Limits.Initial;
32 T.TableLimits.Maximum = Table.Limits.Maximum;
33 return T;
34 }
35
36 WasmYAML::Limits make_limits(const wasm::WasmLimits &Limits) {
37 WasmYAML::Limits L;
38 L.Flags = Limits.Flags;
39 L.Initial = Limits.Initial;
40 L.Maximum = Limits.Maximum;
41 return L;
42 }
2643
2744 ErrorOr WasmDumper::dump() {
2845 auto Y = make_unique();
8198 case wasm::WASM_SEC_IMPORT: {
8299 auto ImportSec = make_unique();
83100 for (auto &Import : Obj.imports()) {
84 WasmYAML::Import Ex;
85 Ex.Module = Import.Module;
86 Ex.Field = Import.Field;
87 Ex.Kind = Import.Kind;
88 if (Ex.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
89 Ex.SigIndex = Import.SigIndex;
90 } else if (Ex.Kind == wasm::WASM_EXTERNAL_GLOBAL) {
91 Ex.GlobalType = Import.GlobalType;
92 Ex.GlobalMutable = Import.GlobalMutable;
93 }
94 ImportSec->Imports.push_back(Ex);
101 WasmYAML::Import Im;
102 Im.Module = Import.Module;
103 Im.Field = Import.Field;
104 Im.Kind = Import.Kind;
105 switch (Im.Kind) {
106 case wasm::WASM_EXTERNAL_FUNCTION:
107 Im.SigIndex = Import.SigIndex;
108 break;
109 case wasm::WASM_EXTERNAL_GLOBAL:
110 Im.Global.Type = Import.Global.Type;
111 Im.Global.Mutable = Import.Global.Mutable;
112 break;
113 case wasm::WASM_EXTERNAL_TABLE:
114 Im.Table = make_table(Import.Table);
115 break;
116 case wasm::WASM_EXTERNAL_MEMORY:
117 Im.Memory = make_limits(Import.Memory);
118 break;
119 }
120 ImportSec->Imports.push_back(Im);
95121 }
96122 S = std::move(ImportSec);
97123 break;
106132 }
107133 case wasm::WASM_SEC_TABLE: {
108134 auto TableSec = make_unique();
109 for (auto &Table : Obj.tables()) {
110 WasmYAML::Table T;
111 T.ElemType = Table.ElemType;
112 T.TableLimits.Flags = Table.Limits.Flags;
113 T.TableLimits.Initial = Table.Limits.Initial;
114 T.TableLimits.Maximum = Table.Limits.Maximum;
115 TableSec->Tables.push_back(T);
135 for (const wasm::WasmTable &Table : Obj.tables()) {
136 TableSec->Tables.push_back(make_table(Table));
116137 }
117138 S = std::move(TableSec);
118139 break;
119140 }
120141 case wasm::WASM_SEC_MEMORY: {
121142 auto MemorySec = make_unique();
122 for (auto &Memory : Obj.memories()) {
123 WasmYAML::Limits L;
124 L.Flags = Memory.Flags;
125 L.Initial = Memory.Initial;
126 L.Maximum = Memory.Maximum;
127 MemorySec->Memories.push_back(L);
143 for (const wasm::WasmLimits &Memory : Obj.memories()) {
144 MemorySec->Memories.push_back(make_limits(Memory));
128145 }
129146 S = std::move(MemorySec);
130147 break;
168168 encodeULEB128(Import.SigIndex, OS);
169169 break;
170170 case wasm::WASM_EXTERNAL_GLOBAL:
171 encodeSLEB128(Import.GlobalType, OS);
172 writeUint8(OS, Import.GlobalMutable);
171 encodeSLEB128(Import.Global.Type, OS);
172 writeUint8(OS, Import.Global.Mutable);
173 break;
174 case wasm::WASM_EXTERNAL_MEMORY:
175 writeLimits(Import.Memory, OS);
176 break;
177 case wasm::WASM_EXTERNAL_TABLE:
178 encodeSLEB128(Import.Table.ElemType, OS);
179 writeLimits(Import.Table.TableLimits, OS);
173180 break;
174181 default:
175182 errs() << "Unknown import type: " << Import.Kind;