llvm.org GIT mirror llvm / 9dcce98
[WebAssembly] Add DataCount section to object files Summary: This ensures that object files will continue to validate as WebAssembly modules in the presence of bulk memory operations. Engines that don't support bulk memory operations will not recognize the DataCount section and will report validation errors, but that's ok because object files aren't supposed to be run directly anyway. Reviewers: aheejin, dschuff, sbc100 Subscribers: jgravelle-google, hiraditya, sunfish, rupprecht, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60623 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358315 91177308-0d34-0410-b5e6-96231b3b80d8 Thomas Lively 6 months ago
21 changed file(s) with 114 addition(s) and 38 deletion(s). Raw diff Collapse all Expand all
246246 Error parseElemSection(ReadContext &Ctx);
247247 Error parseCodeSection(ReadContext &Ctx);
248248 Error parseDataSection(ReadContext &Ctx);
249 Error parseDataCountSection(ReadContext &Ctx);
249250
250251 // Custom section types
251252 Error parseDylinkSection(ReadContext &Ctx);
272273 std::vector Exports;
273274 std::vector ElemSegments;
274275 std::vector DataSegments;
276 llvm::Optional DataCount;
275277 std::vector Functions;
276278 std::vector Symbols;
277279 std::vector DebugNames;
376376 }
377377
378378 std::vector Segments;
379 };
380
381 struct DataCountSection : Section {
382 DataCountSection() : Section(wasm::WASM_SEC_DATACOUNT) {}
383
384 static bool classof(const Section *S) {
385 return S->Type == wasm::WASM_SEC_DATACOUNT;
386 }
387
388 uint32_t Count;
379389 };
380390
381391 struct Object {
325325 void writeFunctionSection(ArrayRef Functions);
326326 void writeExportSection(ArrayRef Exports);
327327 void writeElemSection(ArrayRef TableElems);
328 void writeDataCountSection();
328329 void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
329330 ArrayRef Functions);
330331 void writeDataSection();
845846 for (uint32_t Elem : TableElems)
846847 encodeULEB128(Elem, W.OS);
847848
849 endSection(Section);
850 }
851
852 void WasmObjectWriter::writeDataCountSection() {
853 if (DataSegments.empty())
854 return;
855
856 SectionBookkeeping Section;
857 startSection(Section, wasm::WASM_SEC_DATACOUNT);
858 encodeULEB128(DataSegments.size(), W.OS);
848859 endSection(Section);
849860 }
850861
15991610 writeEventSection(Events);
16001611 writeExportSection(Exports);
16011612 writeElemSection(TableElems);
1613 writeDataCountSection();
16021614 writeCodeSection(Asm, Layout, Functions);
16031615 writeDataSection();
16041616 for (auto &CustomSection : CustomSections)
315315 return parseCodeSection(Ctx);
316316 case wasm::WASM_SEC_DATA:
317317 return parseDataSection(Ctx);
318 case wasm::WASM_SEC_DATACOUNT:
319 return parseDataCountSection(Ctx);
318320 default:
319321 return make_error("Bad section type",
320322 object_error::parse_failed);
12001202 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
12011203 DataSection = Sections.size();
12021204 uint32_t Count = readVaruint32(Ctx);
1205 if (DataCount && Count != DataCount.getValue())
1206 return make_error(
1207 "Number of data segments does not match DataCount section");
12031208 DataSegments.reserve(Count);
12041209 while (Count--) {
12051210 WasmSegment Segment;
12301235 if (Ctx.Ptr != Ctx.End)
12311236 return make_error("Data section ended prematurely",
12321237 object_error::parse_failed);
1238 return Error::success();
1239 }
1240
1241 Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
1242 DataCount = readVaruint32(Ctx);
12331243 return Error::success();
12341244 }
12351245
13981408 ECase(ELEM);
13991409 ECase(CODE);
14001410 ECase(DATA);
1411 ECase(DATACOUNT);
14011412 case wasm::WASM_SEC_CUSTOM:
14021413 Res = S.Name;
14031414 break;
150150 static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) {
151151 commonSectionMapping(IO, Section);
152152 IO.mapRequired("Segments", Section.Segments);
153 }
154
155 static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) {
156 commonSectionMapping(IO, Section);
157 IO.mapRequired("Count", Section.Count);
153158 }
154159
155160 void MappingTraits>::mapping(
256261 Section.reset(new WasmYAML::DataSection());
257262 sectionMapping(IO, *cast(Section.get()));
258263 break;
264 case wasm::WASM_SEC_DATACOUNT:
265 if (!IO.outputting())
266 Section.reset(new WasmYAML::DataCountSection());
267 sectionMapping(IO, *cast(Section.get()));
268 break;
259269 default:
260270 llvm_unreachable("Unknown section type");
261271 }
277287 ECase(ELEM);
278288 ECase(CODE);
279289 ECase(DATA);
290 ECase(DATACOUNT);
280291 #undef ECase
281292 }
282293
88 @foo = global %union.u1 zeroinitializer, align 1
99 @bar = global %union.u1 zeroinitializer, align 1
1010
11 ; CHECK: - Type: DATA
11 ; CHECK: - Type: DATA{{$}}
1212 ; CHECK-NEXT: Segments:
1313 ; CHECK-NEXT: - SectionOffset: 6
1414 ; CHECK-NEXT: InitFlags: 0
4949 ; CHECK-NEXT: SigIndex: 0
5050 ; CHECK-NEXT: - Type: FUNCTION
5151 ; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ]
52 ; CHECK-NEXT: - Type: DATACOUNT
53 ; CHECK-NEXT: Count: 1
5254 ; CHECK-NEXT: - Type: CODE
5355 ; CHECK-NEXT: Relocations:
5456 ; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
5252 # BIN-NEXT: Initial: 0x00000000
5353 # BIN-NEXT: - Type: FUNCTION
5454 # BIN-NEXT: FunctionTypes: [ 0 ]
55 # BIN-NEXT: - Type: DATACOUNT
56 # BIN-NEXT: Count: 1
5557 # BIN-NEXT: - Type: CODE
5658 # BIN-NEXT: Relocations:
5759 # BIN-NEXT: - Type: R_WASM_MEMORY_ADDR_SLEB
9092 # BIN-NEXT: Alignment: 0
9193 # BIN-NEXT: Flags: [ ]
9294 # BIN-NEXT: ...
93
2424 ; CHECK-NEXT: Offset: 90
2525 ; CHECK-NEXT: }
2626 ; CHECK-NEXT: Section {
27 ; CHECK-NEXT: Type: DATACOUNT (0xC)
28 ; CHECK-NEXT: Size: 1
29 ; CHECK-NEXT: Offset: 103
30 ; CHECK-NEXT: }
31 ; CHECK-NEXT: Section {
2732 ; CHECK-NEXT: Type: CODE (0xA)
2833 ; CHECK-NEXT: Size: 4
29 ; CHECK-NEXT: Offset: 103
34 ; CHECK-NEXT: Offset: 110
3035 ; CHECK-NEXT: }
3136 ; CHECK-NEXT: Section {
3237 ; CHECK-NEXT: Type: DATA (0xB)
3338 ; CHECK-NEXT: Size: 19
34 ; CHECK-NEXT: Offset: 113
39 ; CHECK-NEXT: Offset: 120
3540 ; CHECK-NEXT: Segments [
3641 ; CHECK-NEXT: Segment {
3742 ; CHECK-NEXT: Name: .data.foo
4853 ; CHECK-NEXT: Section {
4954 ; CHECK-NEXT: Type: CUSTOM (0x0)
5055 ; CHECK-NEXT: Size: 121
51 ; CHECK-NEXT: Offset: 138
56 ; CHECK-NEXT: Offset: 145
5257 ; CHECK-NEXT: Name: .debug_str
5358 ; CHECK-NEXT: }
5459 ; CHECK-NEXT: Section {
5560 ; CHECK-NEXT: Type: CUSTOM (0x0)
5661 ; CHECK-NEXT: Size: 84
57 ; CHECK-NEXT: Offset: 276
62 ; CHECK-NEXT: Offset: 283
5863 ; CHECK-NEXT: Name: .debug_abbrev
5964 ; CHECK-NEXT: }
6065 ; CHECK-NEXT: Section {
6166 ; CHECK-NEXT: Type: CUSTOM (0x0)
6267 ; CHECK-NEXT: Size: 106
63 ; CHECK-NEXT: Offset: 380
68 ; CHECK-NEXT: Offset: 387
6469 ; CHECK-NEXT: Name: .debug_info
6570 ; CHECK-NEXT: }
6671 ; CHECK-NEXT: Section {
6772 ; CHECK-NEXT: Type: CUSTOM (0x0)
6873 ; CHECK-NEXT: Size: 1
69 ; CHECK-NEXT: Offset: 504
74 ; CHECK-NEXT: Offset: 511
7075 ; CHECK-NEXT: Name: .debug_macinfo
7176 ; CHECK-NEXT: }
7277 ; CHECK-NEXT: Section {
7378 ; CHECK-NEXT: Type: CUSTOM (0x0)
7479 ; CHECK-NEXT: Size: 42
75 ; CHECK-NEXT: Offset: 526
80 ; CHECK-NEXT: Offset: 533
7681 ; CHECK-NEXT: Name: .debug_pubnames
7782 ; CHECK-NEXT: }
7883 ; CHECK-NEXT: Section {
7984 ; CHECK-NEXT: Type: CUSTOM (0x0)
8085 ; CHECK-NEXT: Size: 26
81 ; CHECK-NEXT: Offset: 590
86 ; CHECK-NEXT: Offset: 597
8287 ; CHECK-NEXT: Name: .debug_pubtypes
8388 ; CHECK-NEXT: }
8489 ; CHECK-NEXT: Section {
8590 ; CHECK-NEXT: Type: CUSTOM (0x0)
8691 ; CHECK-NEXT: Size: 57
87 ; CHECK-NEXT: Offset: 638
92 ; CHECK-NEXT: Offset: 645
8893 ; CHECK-NEXT: Name: .debug_line
8994 ; CHECK-NEXT: }
9095 ; CHECK-NEXT: Section {
9196 ; CHECK-NEXT: Type: CUSTOM (0x0)
9297 ; CHECK-NEXT: Size: 88
93 ; CHECK-NEXT: Offset: 713
98 ; CHECK-NEXT: Offset: 720
9499 ; CHECK-NEXT: Name: linking
95100 ; CHECK-NEXT: }
96101 ; CHECK-NEXT: Section {
97102 ; CHECK-NEXT: Type: CUSTOM (0x0)
98103 ; CHECK-NEXT: Size: 9
99 ; CHECK-NEXT: Offset: 815
104 ; CHECK-NEXT: Offset: 822
100105 ; CHECK-NEXT: Name: reloc.DATA
101106 ; CHECK-NEXT: }
102107 ; CHECK-NEXT: Section {
103108 ; CHECK-NEXT: Type: CUSTOM (0x0)
104109 ; CHECK-NEXT: Size: 58
105 ; CHECK-NEXT: Offset: 841
110 ; CHECK-NEXT: Offset: 848
106111 ; CHECK-NEXT: Name: reloc..debug_info
107112 ; CHECK-NEXT: }
108113 ; CHECK-NEXT: Section {
109114 ; CHECK-NEXT: Type: CUSTOM (0x0)
110115 ; CHECK-NEXT: Size: 6
111 ; CHECK-NEXT: Offset: 923
116 ; CHECK-NEXT: Offset: 930
112117 ; CHECK-NEXT: Name: reloc..debug_pubnames
113118 ; CHECK-NEXT: }
114119 ; CHECK-NEXT: Section {
115120 ; CHECK-NEXT: Type: CUSTOM (0x0)
116121 ; CHECK-NEXT: Size: 6
117 ; CHECK-NEXT: Offset: 957
122 ; CHECK-NEXT: Offset: 964
118123 ; CHECK-NEXT: Name: reloc..debug_pubtypes
119124 ; CHECK-NEXT: }
120125 ; CHECK-NEXT: Section {
121126 ; CHECK-NEXT: Type: CUSTOM (0x0)
122127 ; CHECK-NEXT: Size: 6
123 ; CHECK-NEXT: Offset: 991
128 ; CHECK-NEXT: Offset: 998
124129 ; CHECK-NEXT: Name: reloc..debug_line
125130 ; CHECK-NEXT: }
126131 ; CHECK-NEXT: Section {
127132 ; CHECK-NEXT: Type: CUSTOM (0x0)
128133 ; CHECK-NEXT: Size: 77
129 ; CHECK-NEXT: Offset: 1021
134 ; CHECK-NEXT: Offset: 1028
130135 ; CHECK-NEXT: Name: producers
131136 ; CHECK-NEXT: }
132137 ; CHECK-NEXT:]
133138 ; CHECK-NEXT:Relocations [
134 ; CHECK-NEXT: Section (6) DATA {
139 ; CHECK-NEXT: Section (7) DATA {
135140 ; CHECK-NEXT: 0x6 R_WASM_MEMORY_ADDR_I32 myextern 0
136141 ; CHECK-NEXT: 0xF R_WASM_TABLE_INDEX_I32 f2
137142 ; CHECK-NEXT: }
138 ; CHECK-NEXT: Section (9) .debug_info {
143 ; CHECK-NEXT: Section (10) .debug_info {
139144 ; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_abbrev 0
140145 ; CHECK-NEXT: 0xC R_WASM_SECTION_OFFSET_I32 .debug_str 0
141146 ; CHECK-NEXT: 0x12 R_WASM_SECTION_OFFSET_I32 .debug_str 55
150155 ; CHECK-NEXT: 0x5B R_WASM_FUNCTION_OFFSET_I32 f2 0
151156 ; CHECK-NEXT: 0x63 R_WASM_SECTION_OFFSET_I32 .debug_str 118
152157 ; CHECK-NEXT: }
153 ; CHECK-NEXT: Section (11) .debug_pubnames {
158 ; CHECK-NEXT: Section (12) .debug_pubnames {
154159 ; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_info 0
155160 ; CHECK-NEXT: }
156 ; CHECK-NEXT: Section (12) .debug_pubtypes {
161 ; CHECK-NEXT: Section (13) .debug_pubtypes {
157162 ; CHECK-NEXT: 0x6 R_WASM_SECTION_OFFSET_I32 .debug_info 0
158163 ; CHECK-NEXT: }
159 ; CHECK-NEXT: Section (13) .debug_line {
164 ; CHECK-NEXT: Section (14) .debug_line {
160165 ; CHECK-NEXT: 0x2B R_WASM_FUNCTION_OFFSET_I32 f2 0
161166 ; CHECK-NEXT: }
162167 ; CHECK-NEXT:]
204209 ; CHECK-NEXT: Flags [ (0x2)
205210 ; CHECK-NEXT: BINDING_LOCAL (0x2)
206211 ; CHECK-NEXT: ]
207 ; CHECK-NEXT: ElementIndex: 0x6
212 ; CHECK-NEXT: ElementIndex: 0x7
208213 ; CHECK-NEXT: }
209214 ; CHECK-NEXT: Symbol {
210215 ; CHECK-NEXT: Name: .debug_abbrev
212217 ; CHECK-NEXT: Flags [ (0x2)
213218 ; CHECK-NEXT: BINDING_LOCAL (0x2)
214219 ; CHECK-NEXT: ]
215 ; CHECK-NEXT: ElementIndex: 0x7
220 ; CHECK-NEXT: ElementIndex: 0x8
216221 ; CHECK-NEXT: }
217222 ; CHECK-NEXT: Symbol {
218223 ; CHECK-NEXT: Name: .debug_info
220225 ; CHECK-NEXT: Flags [ (0x2)
221226 ; CHECK-NEXT: BINDING_LOCAL (0x2)
222227 ; CHECK-NEXT: ]
223 ; CHECK-NEXT: ElementIndex: 0x8
228 ; CHECK-NEXT: ElementIndex: 0x9
224229 ; CHECK-NEXT: }
225230 ; CHECK-NEXT: Symbol {
226231 ; CHECK-NEXT: Name: .debug_line
228233 ; CHECK-NEXT: Flags [ (0x2)
229234 ; CHECK-NEXT: BINDING_LOCAL (0x2)
230235 ; CHECK-NEXT: ]
231 ; CHECK-NEXT: ElementIndex: 0xC
236 ; CHECK-NEXT: ElementIndex: 0xD
232237 ; CHECK-NEXT: }
233238 ; CHECK-NEXT:]
234239
99 @global3 = global i32 8, align 8, section ".sec2"
1010
1111
12 ; CHECK: - Type: DATA
12 ; CHECK: - Type: DATA{{$}}
1313 ; CHECK-NEXT: Segments:
1414 ; CHECK-NEXT: - SectionOffset: 6
1515 ; CHECK-NEXT: InitFlags: 0
99 @foo = global i64 7, align 4
1010 @bar = hidden global i32* @myimport, align 4
1111
12 ; CHECK: - Type: DATA
12 ; CHECK: - Type: DATA{{$}}
1313 ; CHECK-NEXT: Relocations:
1414 ; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
1515 ; CHECK-NEXT: Index: 2
5757 ; CHECK-NEXT: Opcode: I32_CONST
5858 ; CHECK-NEXT: Value: 1
5959 ; CHECK-NEXT: Functions: [ 1, 2 ]
60 ; CHECK: - Type: DATA
60 ; CHECK: - Type: DATA{{$}}
6161 ; CHECK-NEXT: Relocations:
6262 ; CHECK-NEXT: - Type: R_WASM_TABLE_INDEX_I32
6363 ; CHECK-NEXT: Index: 3
6060 ; CHECK-NEXT: Opcode: I32_CONST
6161 ; CHECK-NEXT: Value: 1
6262 ; CHECK-NEXT: Functions: [ 5, 7 ]
63 ; CHECK-NEXT: - Type: DATACOUNT
64 ; CHECK-NEXT: Count: 1
6365 ; CHECK-NEXT: - Type: CODE
6466 ; CHECK-NEXT: Relocations:
6567 ; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
2323
2424 ; CHECK: Format: WASM
2525 ; CHECK: Relocations [
26 ; CHECK-NEXT: Section (4) CODE {
26 ; CHECK-NEXT: Section (5) CODE {
2727 ; CHECK-NEXT: Relocation {
2828 ; CHECK-NEXT: Type: R_WASM_MEMORY_ADDR_LEB (3)
2929 ; CHECK-NEXT: Offset: 0x9
1212
1313 ; CHECK: Format: WASM
1414 ; CHECK: Relocations [
15 ; CHECK-NEXT: Section (2) DATA {
15 ; CHECK-NEXT: Section (3) DATA {
1616 ; CHECK-NEXT: Relocation {
1717 ; CHECK-NEXT: Type: R_WASM_MEMORY_ADDR_I32 (5)
1818 ; CHECK-NEXT: Offset: 0x13
8383 # CHECK-NEXT: GlobalMutable: true
8484 # CHECK-NEXT: - Type: FUNCTION
8585 # CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
86 # CHECK-NEXT: - Type: DATACOUNT
87 # CHECK-NEXT: Count: 1
8688 # CHECK-NEXT: - Type: CODE
8789 # CHECK-NEXT: Relocations:
8890 # CHECK-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
88 @b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8
99
1010
11 ; CHECK: - Type: DATA
11 ; CHECK: - Type: DATA{{$}}
1212 ; CHECK-NEXT: Relocations:
1313 ; CHECK-NEXT: - Type: R_WASM_MEMORY_ADDR_I32
1414 ; CHECK-NEXT: Index: 0
7272 ; CHECK-NEXT: Opcode: I32_CONST
7373 ; CHECK-NEXT: Value: 1
7474 ; CHECK-NEXT: Functions: [ 0 ]
75 ; CHECK-NEXT: - Type: DATACOUNT
76 ; CHECK-NEXT: Count: 3
7577 ; CHECK-NEXT: - Type: CODE
7678 ; CHECK-NEXT: Relocations:
7779 ; CHECK-NEXT: - Type: R_WASM_FUNCTION_INDEX_LEB
3131 static const EnumEntry WasmSectionTypes[] = {
3232 #define ENUM_ENTRY(X) \
3333 { #X, wasm::WASM_SEC_##X }
34 ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
35 ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
36 ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
37 ENUM_ENTRY(START), ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE),
38 ENUM_ENTRY(DATA),
34 ENUM_ENTRY(CUSTOM), ENUM_ENTRY(TYPE), ENUM_ENTRY(IMPORT),
35 ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE), ENUM_ENTRY(MEMORY),
36 ENUM_ENTRY(GLOBAL), ENUM_ENTRY(EVENT), ENUM_ENTRY(EXPORT),
37 ENUM_ENTRY(START), ENUM_ENTRY(ELEM), ENUM_ENTRY(CODE),
38 ENUM_ENTRY(DATA), ENUM_ENTRY(DATACOUNT),
3939 #undef ENUM_ENTRY
4040 };
4141
352352 S = std::move(DataSec);
353353 break;
354354 }
355 case wasm::WASM_SEC_DATACOUNT: {
356 auto DataCountSec = make_unique();
357 DataCountSec->Count = Obj.dataSegments().size();
358 S = std::move(DataCountSec);
359 break;
360 }
355361 default:
356362 llvm_unreachable("Unknown section type");
357363 break;
4242 int writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
4343 int writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
4444 int writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
45 int writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section);
4546
4647 // Custom section types
4748 int writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
513514 return 0;
514515 }
515516
517 int WasmWriter::writeSectionContent(raw_ostream &OS,
518 WasmYAML::DataCountSection &Section) {
519 encodeULEB128(Section.Count, OS);
520 return 0;
521 }
522
516523 int WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
517524 uint32_t SectionIndex) {
518525 switch (Sec.Type) {
613620 } else if (auto S = dyn_cast(Sec.get())) {
614621 if (auto Err = writeSectionContent(StringStream, *S))
615622 return Err;
623 } else if (auto S = dyn_cast(Sec.get())) {
624 if (auto Err = writeSectionContent(StringStream, *S))
625 return Err;
616626 } else {
617627 errs() << "Unknown section type: " << Sec->Type << "\n";
618628 return 1;