llvm.org GIT mirror llvm / 3981231
[WebAssembly] Target features section Summary: Implements a new target features section in assembly and object files that records what features are used, required, and disallowed in WebAssembly objects. The linker uses this information to ensure that all objects participating in a link are feature-compatible and records the set of used features in the output binary for use by optimizers and other tools later in the toolchain. The "atomics" feature is always required or disallowed to prevent linking code with stripped atomics into multithreaded binaries. Other features are marked used if they are enabled globally or on any function in a module. Future CLs will add linker flags for ignoring feature compatibility checks and for specifying the set of allowed features, implement using the presence of the "atomics" feature to control the type of memory and segments in the linked binary, and add front-end flags for relaxing the linkage policy for atomics. Reviewers: aheejin, sbc100, dschuff Subscribers: jgravelle-google, hiraditya, sunfish, mgrang, jfb, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59173 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356610 91177308-0d34-0410-b5e6-96231b3b80d8 Thomas Lively 4 months ago
23 changed file(s) with 348 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
4545 std::vector> Languages;
4646 std::vector> Tools;
4747 std::vector> SDKs;
48 };
49
50 struct WasmFeatureEntry {
51 uint8_t Prefix;
52 std::string Name;
4853 };
4954
5055 struct WasmExport {
252257 WASM_SEGMENT_HAS_MEMINDEX = 0x02,
253258 };
254259
260 // Feature policy prefixes used in the custom "target_features" section
261 enum : uint8_t {
262 WASM_FEATURE_PREFIX_USED = '+',
263 WASM_FEATURE_PREFIX_REQUIRED = '=',
264 WASM_FEATURE_PREFIX_DISALLOWED = '-',
265 };
266
255267 // Kind codes used in the custom "name" section
256268 enum : unsigned {
257269 WASM_NAMES_FUNCTION = 0x1,
129129
130130 const wasm::WasmDylinkInfo &dylinkInfo() const { return DylinkInfo; }
131131 const wasm::WasmProducerInfo &getProducerInfo() const { return ProducerInfo; }
132 ArrayRef getTargetFeatures() const {
133 return TargetFeatures;
134 }
132135 ArrayRef types() const { return Signatures; }
133136 ArrayRef functionTypes() const { return FunctionTypes; }
134137 ArrayRef imports() const { return Imports; }
251254 Error parseLinkingSectionSymtab(ReadContext &Ctx);
252255 Error parseLinkingSectionComdat(ReadContext &Ctx);
253256 Error parseProducersSection(ReadContext &Ctx);
257 Error parseTargetFeaturesSection(ReadContext &Ctx);
254258 Error parseRelocSection(StringRef Name, ReadContext &Ctx);
255259
256260 wasm::WasmObjectHeader Header;
257261 std::vector Sections;
258262 wasm::WasmDylinkInfo DylinkInfo;
259263 wasm::WasmProducerInfo ProducerInfo;
264 std::vector TargetFeatures;
260265 std::vector Signatures;
261266 std::vector FunctionTypes;
262267 std::vector Tables;
317322 WASM_SEC_ORDER_NAME,
318323 // "producers" section must appear after "name" section.
319324 WASM_SEC_ORDER_PRODUCERS,
325 // "target_features" section must appear after producers section
326 WASM_SEC_ORDER_TARGET_FEATURES,
320327
321328 // Must be last
322329 WASM_NUM_SEC_ORDERS
3737 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
3838 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
3939 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, FeaturePolicyPrefix)
4041
4142 struct FileHeader {
4243 yaml::Hex32 Version;
127128 std::string Version;
128129 };
129130
131 struct FeatureEntry {
132 FeaturePolicyPrefix Prefix;
133 std::string Name;
134 };
135
130136 struct SegmentInfo {
131137 uint32_t Index;
132138 StringRef Name;
239245 std::vector Languages;
240246 std::vector Tools;
241247 std::vector SDKs;
248 };
249
250 struct TargetFeaturesSection : CustomSection {
251 TargetFeaturesSection() : CustomSection("target_features") {}
252
253 static bool classof(const Section *S) {
254 auto C = dyn_cast(S);
255 return C && C->Name == "target_features";
256 }
257
258 std::vector Features;
242259 };
243260
244261 struct TypeSection : Section {
384401 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
385402 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
386403 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::ProducerEntry)
404 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::FeatureEntry)
387405 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
388406 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
389407 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
466484 static void mapping(IO &IO, WasmYAML::ProducerEntry &ProducerEntry);
467485 };
468486
487 template <> struct ScalarEnumerationTraits {
488 static void enumeration(IO &IO, WasmYAML::FeaturePolicyPrefix &Prefix);
489 };
490
491 template <> struct MappingTraits {
492 static void mapping(IO &IO, WasmYAML::FeatureEntry &FeatureEntry);
493 };
494
469495 template <> struct MappingTraits {
470496 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
471497 };
134134 SectionKind Kind;
135135 };
136136 static SectionType SectionTypes[] = {
137 { ".text", SectionKind::getText() },
138 { ".rodata", SectionKind::getReadOnly() },
139 { ".data", SectionKind::getData() },
137 {".text", SectionKind::getText()},
138 {".rodata", SectionKind::getReadOnly()},
139 {".data", SectionKind::getData()},
140 {".custom_section", SectionKind::getMetadata()},
140141 // TODO: add more types.
141142 };
142143 for (size_t I = 0; I < sizeof(SectionTypes) / sizeof(SectionType); I++) {
249249 // section.
250250 std::vector CustomSections;
251251 std::unique_ptr ProducersSection;
252 std::unique_ptr TargetFeaturesSection;
252253 // Relocations for fixing up references in the custom sections.
253254 DenseMap>
254255 CustomSectionsRelocations;
290291 DataLocations.clear();
291292 CustomSections.clear();
292293 ProducersSection.reset();
294 TargetFeaturesSection.reset();
293295 CustomSectionsRelocations.clear();
294296 SignatureIndices.clear();
295297 Signatures.clear();
12851287 Twine(SectionName));
12861288 }
12871289
1288 // Separate out the producers section
1290 // Separate out the producers and target features sections
12891291 if (Name == "producers") {
12901292 ProducersSection = llvm::make_unique(Name, &Section);
1293 continue;
1294 }
1295 if (Name == "target_features") {
1296 TargetFeaturesSection =
1297 llvm::make_unique(Name, &Section);
12911298 continue;
12921299 }
12931300
15921599 writeCustomRelocSections();
15931600 if (ProducersSection)
15941601 writeCustomSection(*ProducersSection, Asm, Layout);
1602 if (TargetFeaturesSection)
1603 writeCustomSection(*TargetFeaturesSection, Asm, Layout);
15951604
15961605 // TODO: Translate the .comment section to the output.
15971606 return W.OS.tell() - StartOffset;
714714 return Error::success();
715715 }
716716
717 Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
718 llvm::SmallSet FeaturesSeen;
719 uint32_t FeatureCount = readVaruint32(Ctx);
720 for (size_t I = 0; I < FeatureCount; ++I) {
721 wasm::WasmFeatureEntry Feature;
722 Feature.Prefix = readUint8(Ctx);
723 switch (Feature.Prefix) {
724 case wasm::WASM_FEATURE_PREFIX_USED:
725 case wasm::WASM_FEATURE_PREFIX_REQUIRED:
726 case wasm::WASM_FEATURE_PREFIX_DISALLOWED:
727 break;
728 default:
729 return make_error("Unknown feature policy prefix",
730 object_error::parse_failed);
731 }
732 Feature.Name = readString(Ctx);
733 if (!FeaturesSeen.insert(Feature.Name).second)
734 return make_error(
735 "Target features section contains repeated feature \"" +
736 Feature.Name + "\"",
737 object_error::parse_failed);
738 TargetFeatures.push_back(Feature);
739 }
740 if (Ctx.Ptr != Ctx.End)
741 return make_error(
742 "Target features section ended prematurely",
743 object_error::parse_failed);
744 return Error::success();
745 }
746
717747 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
718748 uint32_t SectionIndex = readVaruint32(Ctx);
719749 if (SectionIndex >= Sections.size())
814844 return Err;
815845 } else if (Sec.Name == "producers") {
816846 if (Error Err = parseProducersSection(Ctx))
847 return Err;
848 } else if (Sec.Name == "target_features") {
849 if (Error Err = parseTargetFeaturesSection(Ctx))
817850 return Err;
818851 } else if (Sec.Name.startswith("reloc.")) {
819852 if (Error Err = parseRelocSection(Sec.Name, Ctx))
15271560 .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
15281561 .Case("name", WASM_SEC_ORDER_NAME)
15291562 .Case("producers", WASM_SEC_ORDER_PRODUCERS)
1563 .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
15301564 .Default(WASM_SEC_ORDER_NONE);
15311565 case wasm::WASM_SEC_TYPE:
15321566 return WASM_SEC_ORDER_TYPE;
15831617 {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME}, // WASM_SEC_ORDER_LINKING,
15841618 {}, // WASM_SEC_ORDER_RELOC (can be repeated),
15851619 {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS}, // WASM_SEC_ORDER_NAME,
1586 {WASM_SEC_ORDER_PRODUCERS}, // WASM_SEC_ORDER_PRODUCERS,
1620 {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES}, // WASM_SEC_ORDER_PRODUCERS,
1621 {WASM_SEC_ORDER_TARGET_FEATURES} // WASM_SEC_ORDER_TARGET_FEATURES
15871622 };
15881623
15891624 bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID,
7878 IO.mapOptional("Languages", Section.Languages);
7979 IO.mapOptional("Tools", Section.Tools);
8080 IO.mapOptional("SDKs", Section.SDKs);
81 }
82
83 static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) {
84 commonSectionMapping(IO, Section);
85 IO.mapRequired("Name", Section.Name);
86 IO.mapRequired("Features", Section.Features);
8187 }
8288
8389 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
179185 if (!IO.outputting())
180186 Section.reset(new WasmYAML::ProducersSection());
181187 sectionMapping(IO, *cast(Section.get()));
188 } else if (SectionName == "target_features") {
189 if (!IO.outputting())
190 Section.reset(new WasmYAML::TargetFeaturesSection());
191 sectionMapping(IO, *cast(Section.get()));
182192 } else {
183193 if (!IO.outputting())
184194 Section.reset(new WasmYAML::CustomSection(SectionName));
307317 IO &IO, WasmYAML::ProducerEntry &ProducerEntry) {
308318 IO.mapRequired("Name", ProducerEntry.Name);
309319 IO.mapRequired("Version", ProducerEntry.Version);
320 }
321
322 void ScalarEnumerationTraits::enumeration(
323 IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) {
324 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X);
325 ECase(USED);
326 ECase(REQUIRED);
327 ECase(DISALLOWED);
328 #undef ECase
329 }
330
331 void MappingTraits::mapping(
332 IO &IO, WasmYAML::FeatureEntry &FeatureEntry) {
333 IO.mapRequired("Prefix", FeatureEntry.Prefix);
334 IO.mapRequired("Name", FeatureEntry.Name);
310335 }
311336
312337 void MappingTraits::mapping(
2020 #include "WebAssemblyMCInstLower.h"
2121 #include "WebAssemblyMachineFunctionInfo.h"
2222 #include "WebAssemblyRegisterInfo.h"
23 #include "WebAssemblyTargetMachine.h"
2324 #include "llvm/ADT/SmallSet.h"
2425 #include "llvm/ADT/StringExtras.h"
26 #include "llvm/BinaryFormat/Wasm.h"
2527 #include "llvm/CodeGen/Analysis.h"
2628 #include "llvm/CodeGen/AsmPrinter.h"
2729 #include "llvm/CodeGen/MachineConstantPool.h"
158160 }
159161
160162 EmitProducerInfo(M);
163 EmitTargetFeatures();
161164 }
162165
163166 void WebAssemblyAsmPrinter::EmitProducerInfo(Module &M) {
209212 }
210213 OutStreamer->PopSection();
211214 }
215 }
216
217 void WebAssemblyAsmPrinter::EmitTargetFeatures() {
218 static const std::pair FeaturePairs[] = {
219 {WebAssembly::FeatureAtomics, "atomics"},
220 {WebAssembly::FeatureBulkMemory, "bulk-memory"},
221 {WebAssembly::FeatureExceptionHandling, "exception-handling"},
222 {WebAssembly::FeatureNontrappingFPToInt, "nontrapping-fptoint"},
223 {WebAssembly::FeatureSignExt, "sign-ext"},
224 {WebAssembly::FeatureSIMD128, "simd128"},
225 };
226
227 struct FeatureEntry {
228 uint8_t Prefix;
229 StringRef Name;
230 };
231
232 FeatureBitset UsedFeatures =
233 static_cast(TM).getUsedFeatures();
234
235 // Calculate the features and linkage policies to emit
236 SmallVector EmittedFeatures;
237 for (auto &F : FeaturePairs) {
238 FeatureEntry Entry;
239 Entry.Name = F.second;
240 if (F.first == WebAssembly::FeatureAtomics) {
241 // "atomics" is special: code compiled without atomics may have had its
242 // atomics lowered to nonatomic operations. Such code would be dangerous
243 // to mix with proper atomics, so it is always Required or Disallowed.
244 Entry.Prefix = UsedFeatures[F.first] ? wasm::WASM_FEATURE_PREFIX_REQUIRED
245 : wasm::WASM_FEATURE_PREFIX_DISALLOWED;
246 EmittedFeatures.push_back(Entry);
247 } else {
248 // Other features are marked Used or not mentioned
249 if (UsedFeatures[F.first]) {
250 Entry.Prefix = wasm::WASM_FEATURE_PREFIX_USED;
251 EmittedFeatures.push_back(Entry);
252 }
253 }
254 }
255
256 // Emit features and linkage policies into the "target_features" section
257 MCSectionWasm *FeaturesSection = OutContext.getWasmSection(
258 ".custom_section.target_features", SectionKind::getMetadata());
259 OutStreamer->PushSection();
260 OutStreamer->SwitchSection(FeaturesSection);
261
262 OutStreamer->EmitULEB128IntValue(EmittedFeatures.size());
263 for (auto &F : EmittedFeatures) {
264 OutStreamer->EmitIntValue(F.Prefix, 1);
265 OutStreamer->EmitULEB128IntValue(F.Name.size());
266 OutStreamer->EmitBytes(F.Name);
267 }
268
269 OutStreamer->PopSection();
212270 }
213271
214272 void WebAssemblyAsmPrinter::EmitConstantPool() {
5858
5959 void EmitEndOfAsmFile(Module &M) override;
6060 void EmitProducerInfo(Module &M);
61 void EmitTargetFeatures();
6162 void EmitJumpTableInfo() override;
6263 void EmitConstantPool() override;
6364 void EmitFunctionBodyStart() override;
0 ; RUN: llc < %s | FileCheck %s --check-prefixes CHECK,ATTRS
1 ; RUN: llc < %s -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
2 ; RUN; llc < %s -mattr=+atomics | FileCheck %s --check-prefixes CHECK,ATOMICS
3 ; RUN: llc < %s -mcpu=bleeding-edge | FileCheck %s --check-prefixes CHECK,BLEEDING-EDGE
4
5 ; Test that codegen emits target features from the command line or
6 ; function attributes correctly.
7
8 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
9 target triple = "wasm32-unknown-unknown"
10
11 define void @foo() #0 {
12 ret void
13 }
14
15 define void @bar() #1 {
16 ret void
17 }
18
19 attributes #0 = { "target-features"="+sign-ext" }
20 attributes #1 = { "target-features"="+nontrapping-fptoint" }
21
22 ; CHECK-LABEL: .custom_section.target_features,"",@
23
24 ; -atomics, +sign_ext
25 ; ATTRS-NEXT: .int8 3
26 ; ATTRS-NEXT: .int8 45
27 ; ATTRS-NEXT: .int8 7
28 ; ATTRS-NEXT: .ascii "atomics"
29 ; ATTRS-NEXT: .int8 43
30 ; ATTRS-NEXT: .int8 19
31 ; ATTRS-NEXT: .ascii "nontrapping-fptoint"
32 ; ATTRS-NEXT: .int8 43
33 ; ATTRS-NEXT: int8 8
34 ; ATTRS-NEXT: .ascii "sign-ext"
35
36 ; -atomics, +simd128
37 ; SIMD128-NEXT: .int8 2
38 ; SIMD128-NEXT: .int8 45
39 ; SIMD128-NEXT: .int8 7
40 ; SIMD128-NEXT: .ascii "atomics"
41 ; SIMD128-NEXT: .int8 43
42 ; SIMD128-NEXT: .int8 7
43 ; SIMD128-NEXT: .ascii "simd128"
44
45 ; =atomics
46 ; ATOMICS-NEXT: .int8 1
47 ; ATOMICS-NEXT: .int8 61
48 ; ATOMICS-NEXT: .int8 7
49 ; ATOMICS-NEXT: .ascii "atomics"
50
51 ; =atomics, +nontrapping-fptoint, +sign-ext, +simd128
52 ; BLEEDING-EDGE-NEXT: .int8 4
53 ; BLEEDING-EDGE-NEXT: .int8 61
54 ; BLEEDING-EDGE-NEXT: .int8 7
55 ; BLEEDING-EDGE-NEXT: .ascii "atomics"
56 ; BLEEDING-EDGE-NEXT: .int8 43
57 ; BLEEDING-EDGE-NEXT: .int8 19
58 ; BLEEDING-EDGE-NEXT: .ascii "nontrapping-fptoint"
59 ; BLEEDING-EDGE-NEXT: .int8 43
60 ; BLEEDING-EDGE-NEXT: .int8 8
61 ; BLEEDING-EDGE-NEXT: .ascii "sign-ext"
62 ; BLEEDING-EDGE-NEXT: .int8 43
63 ; BLEEDING-EDGE-NEXT: .int8 7
64 ; BLEEDING-EDGE-NEXT: .ascii "simd128"
65
66 ; CHECK-NEXT: .text
2323 ; CHECK-NEXT: Name: .data
2424 ; CHECK-NEXT: Alignment: 0
2525 ; CHECK-NEXT: Flags: [ ]
26 ; CHECK-NEXT: - Type: CUSTOM
27 ; CHECK-NEXT: Name: target_features
28 ; CHECK-NEXT: Features:
29 ; CHECK-NEXT: - Prefix: DISALLOWED
30 ; CHECK-NEXT: Name: atomics
2631 ; CHECK-NEXT: ...
8686 ; CHECK-NEXT: Name: bar
8787 ; CHECK-NEXT: Flags: [ UNDEFINED ]
8888 ; CHECK-NEXT: Function: 0
89 ; CHECK-NEXT: - Type: CUSTOM
90 ; CHECK-NEXT: Name: target_features
91 ; CHECK-NEXT: Features:
92 ; CHECK-NEXT: - Prefix: DISALLOWED
93 ; CHECK-NEXT: Name: atomics
8994 ; CHECK-NEXT: ...
7777 ; CHECK-NEXT: Name: .bss.bar
7878 ; CHECK-NEXT: Alignment: 0
7979 ; CHECK-NEXT: Flags: [ ]
80 ; CHECK-NEXT: - Type: CUSTOM
81 ; CHECK-NEXT: Name: target_features
82 ; CHECK-NEXT: Features:
83 ; CHECK-NEXT: - Prefix: DISALLOWED
84 ; CHECK-NEXT: Name: atomics
8085 ; CHECK-NEXT: ...
118118 ; CHECK-NEXT: Index: 3
119119 ; CHECK-NEXT: - Kind: DATA
120120 ; CHECK-NEXT: Index: 0
121 ; CHECK-NEXT: - Type: CUSTOM
122 ; CHECK-NEXT: Name: target_features
123 ; CHECK-NEXT: Features:
124 ; CHECK-NEXT: - Prefix: DISALLOWED
125 ; CHECK-NEXT: Name: atomics
121126 ; CHECK-NEXT: ...
128128 ; CHECK-NEXT: Size: 77
129129 ; CHECK-NEXT: Offset: 1021
130130 ; CHECK-NEXT: Name: producers
131 ; CHECK-NEXT: }
132 ; CHECK-NEXT: Section {
133 ; CHECK-NEXT: Type: CUSTOM (0x0)
134 ; CHECK-NEXT: Size: 10
135 ; CHECK-NEXT: Offset: 1114
136 ; CHECK-NEXT: Name: target_features
131137 ; CHECK-NEXT: }
132138 ; CHECK-NEXT:]
133139 ; CHECK-NEXT:Relocations [
6969 ; CHECK-NEXT: Name: .sec2
7070 ; CHECK-NEXT: Alignment: 3
7171 ; CHECK-NEXT: Flags: [ ]
72 ; CHECK-NEXT: - Type: CUSTOM
73 ; CHECK-NEXT: Name: target_features
74 ; CHECK-NEXT: Features:
75 ; CHECK-NEXT: - Prefix: DISALLOWED
76 ; CHECK-NEXT: Name: atomics
7277 ; CHECK-NEXT: ...
180180 ; CHECK-NEXT: Symbol: 10
181181 ; CHECK-NEXT: - Priority: 65535
182182 ; CHECK-NEXT: Symbol: 7
183 ; CHECK-NEXT: - Type: CUSTOM
184 ; CHECK-NEXT: Name: target_features
185 ; CHECK-NEXT: Features:
186 ; CHECK-NEXT: - Prefix: DISALLOWED
187 ; CHECK-NEXT: Name: atomics
183188 ; CHECK-NEXT: ...
2424 ; CHECK-NEXT: Name: hiddenVis
2525 ; CHECK-NEXT: Flags: [ VISIBILITY_HIDDEN ]
2626 ; CHECK-NEXT: Function: 1
27 ; CHECK-NEXT: - Type: CUSTOM
28 ; CHECK-NEXT: Name: target_features
29 ; CHECK-NEXT: Features:
30 ; CHECK-NEXT: - Prefix: DISALLOWED
31 ; CHECK-NEXT: Name: atomics
2732 ; CHECK-NEXT: ...
206206 ; CHECK-NEXT: Name: .data.alias_address
207207 ; CHECK-NEXT: Alignment: 3
208208 ; CHECK-NEXT: Flags: [ ]
209 ; CHECK-NEXT: - Type: CUSTOM
210 ; CHECK-NEXT: Name: target_features
211 ; CHECK-NEXT: Features:
212 ; CHECK-NEXT: - Prefix: DISALLOWED
213 ; CHECK-NEXT: Name: atomics
209214 ; CHECK-NEXT: ...
210215
211216 ; CHECK-SYMS: SYMBOL TABLE:
2929 ; CHECK-NEXT: Kind: DATA
3030 ; CHECK-NEXT: Name: weak_external_data
3131 ; CHECK-NEXT: Flags: [ BINDING_WEAK, UNDEFINED ]
32 ; CHECK-NEXT: - Type: CUSTOM
33 ; CHECK-NEXT: Name: target_features
34 ; CHECK-NEXT: Features:
35 ; CHECK-NEXT: - Prefix: DISALLOWED
36 ; CHECK-NEXT: Name: atomics
3237 ; CHECK-NEXT: ...
0 # RUN: yaml2obj %s | obj2yaml | FileCheck %s
1 --- !WASM
2 FileHeader:
3 Version: 0x00000001
4 Sections:
5 - Type: CUSTOM
6 Name: target_features
7 Features:
8 - Prefix: USED
9 Name: "foo"
10 - Prefix: REQUIRED
11 Name: "bar"
12 - Prefix: DISALLOWED
13 Name: ""
14 ...
15 # CHECK-LABEL: Sections:
16 # CHECK-NEXT: - Type: CUSTOM
17 # CHECK-NEXT: Name: target_features
18 # CHECK-NEXT: Features:
19 # CHECK-NEXT: - Prefix: USED
20 # CHECK-NEXT: Name: foo
21 # CHECK-NEXT: - Prefix: REQUIRED
22 # CHECK-NEXT: Name: bar
23 # CHECK-NEXT: - Prefix: DISALLOWED
24 # CHECK-NEXT: Name: ''
154154 ProducersSec->SDKs.push_back(Producer);
155155 }
156156 CustomSec = std::move(ProducersSec);
157 } else if (WasmSec.Name == "target_features") {
158 std::unique_ptr TargetFeaturesSec =
159 make_unique();
160 for (auto &E : Obj.getTargetFeatures()) {
161 WasmYAML::FeatureEntry Feature;
162 Feature.Prefix = E.Prefix;
163 Feature.Name = E.Name;
164 TargetFeaturesSec->Features.push_back(Feature);
165 }
166 CustomSec = std::move(TargetFeaturesSec);
157167 } else {
158168 CustomSec = make_unique(WasmSec.Name);
159169 }
4848 int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
4949 int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
5050 int writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section);
51 int writeSectionContent(raw_ostream &OS,
52 WasmYAML::TargetFeaturesSection &Section);
5153 WasmYAML::Object &Obj;
5254 uint32_t NumImportedFunctions = 0;
5355 uint32_t NumImportedGlobals = 0;
279281 }
280282
281283 int WasmWriter::writeSectionContent(raw_ostream &OS,
284 WasmYAML::TargetFeaturesSection &Section) {
285 writeStringRef(Section.Name, OS);
286 encodeULEB128(Section.Features.size(), OS);
287 for (auto &E : Section.Features) {
288 writeUint8(OS, E.Prefix);
289 writeStringRef(E.Name, OS);
290 }
291 return 0;
292 }
293
294 int WasmWriter::writeSectionContent(raw_ostream &OS,
282295 WasmYAML::CustomSection &Section) {
283296 if (auto S = dyn_cast(&Section)) {
284297 if (auto Err = writeSectionContent(OS, *S))
290303 if (auto Err = writeSectionContent(OS, *S))
291304 return Err;
292305 } else if (auto S = dyn_cast(&Section)) {
306 if (auto Err = writeSectionContent(OS, *S))
307 return Err;
308 } else if (auto S = dyn_cast(&Section)) {
293309 if (auto Err = writeSectionContent(OS, *S))
294310 return Err;
295311 } else {