llvm.org GIT mirror llvm / e286417
[WebAssembly] Allow each data segment to specify its own alignment Also, add a flags field as we will almost certainly be needing that soon too. Differential Revision: https://reviews.llvm.org/D38296 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314534 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 11 months ago
19 changed file(s) with 88 addition(s) and 62 deletion(s). Raw diff Collapse all Expand all
9797 WasmInitExpr Offset;
9898 ArrayRef Content;
9999 StringRef Name;
100 uint32_t Alignment;
101 uint32_t Flags;
100102 };
101103
102104 struct WasmElemSegment {
114116
115117 struct WasmLinkingData {
116118 uint32_t DataSize;
117 uint32_t DataAlignment;
118119 };
119120
120121 enum : unsigned {
184185 WASM_SYMBOL_INFO = 0x2,
185186 WASM_DATA_SIZE = 0x3,
186187 WASM_DATA_ALIGNMENT = 0x4,
187 WASM_SEGMENT_NAMES = 0x5,
188 WASM_SEGMENT_INFO = 0x5,
188189 };
189190
190191 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
108108 StringRef Name;
109109 };
110110
111 struct SegmentInfo {
112 uint32_t Index;
113 StringRef Name;
114 uint32_t Alignment;
115 uint32_t Flags;
116 };
117
111118 struct Signature {
112119 uint32_t Index;
113120 SignatureForm Form = wasm::WASM_TYPE_FUNC;
160167 }
161168
162169 uint32_t DataSize;
163 uint32_t DataAlignment;
164170 std::vector SymbolInfos;
165 std::vector<NameEntry> SegmentNames;
171 std::vector<SegmentInfo> SegmentInfos;
166172 };
167173
168174 struct TypeSection : Section {
297303 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::LocalDecl)
298304 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::Relocation)
299305 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
306 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
300307 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
301308
302309 namespace llvm {
354361 static void mapping(IO &IO, WasmYAML::NameEntry &NameEntry);
355362 };
356363
364 template <> struct MappingTraits {
365 static void mapping(IO &IO, WasmYAML::SegmentInfo &SegmentInfo);
366 };
367
357368 template <> struct MappingTraits {
358369 static void mapping(IO &IO, WasmYAML::LocalDecl &LocalDecl);
359370 };
103103 MCSectionWasm *Section;
104104 StringRef Name;
105105 uint32_t Offset;
106 uint32_t Alignment;
107 uint32_t Flags;
106108 SmallVector Data;
107109 };
108110
281283 void writeDataRelocSection();
282284 void writeLinkingMetaDataSection(
283285 ArrayRef Segments, uint32_t DataSize,
284 uint32_t DataAlignment,
285286 SmallVector, 4> SymbolFlags,
286287 bool HasStackPointer, uint32_t StackPointerGlobal);
287288
498499 }
499500
500501 static void addData(SmallVectorImpl &DataBytes,
501 MCSectionWasm &DataSection, uint32_t &DataAlignment) {
502 MCSectionWasm &DataSection) {
503 DEBUG(errs() << "addData: " << DataSection.getSectionName() << "\n");
504
502505 DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
503 DataAlignment = std::max(DataAlignment, DataSection.getAlignment());
504 DEBUG(errs() << "addData: " << DataSection.getSectionName() << "\n");
505506
506507 for (const MCFragment &Frag : DataSection) {
507508 if (Frag.hasInstructions())
913914
914915 void WasmObjectWriter::writeLinkingMetaDataSection(
915916 ArrayRef Segments, uint32_t DataSize,
916 uint32_t DataAlignment,
917917 SmallVector, 4> SymbolFlags,
918918 bool HasStackPointer, uint32_t StackPointerGlobal) {
919919 SectionBookkeeping Section;
940940 startSection(SubSection, wasm::WASM_DATA_SIZE);
941941 encodeULEB128(DataSize, getStream());
942942 endSection(SubSection);
943
944 startSection(SubSection, wasm::WASM_DATA_ALIGNMENT);
945 encodeULEB128(DataAlignment, getStream());
946 endSection(SubSection);
947943 }
948944
949945 if (Segments.size()) {
950 startSection(SubSection, wasm::WASM_SEGMENT_NAMES);
946 startSection(SubSection, wasm::WASM_SEGMENT_INFO);
951947 encodeULEB128(Segments.size(), getStream());
952 for (const WasmDataSegment &Segment : Segments)
948 for (const WasmDataSegment &Segment : Segments) {
953949 writeString(Segment.Name);
950 encodeULEB128(Segment.Alignment, getStream());
951 encodeULEB128(Segment.Flags, getStream());
952 }
954953 endSection(SubSection);
955954 }
956955
997996 SmallPtrSet IsAddressTaken;
998997 unsigned NumFuncImports = 0;
999998 SmallVector DataSegments;
1000 uint32_t DataAlignment = 1;
1001999 uint32_t StackPointerGlobal = 0;
10021000 uint32_t DataSize = 0;
10031001 bool HasStackPointer = false;
11431141 Segment.Name = Section.getSectionName();
11441142 Segment.Offset = DataSize;
11451143 Segment.Section = &Section;
1146 addData(Segment.Data, Section, DataAlignment);
1144 addData(Segment.Data, Section);
1145 Segment.Alignment = Section.getAlignment();
1146 Segment.Flags = 0;
11471147 DataSize += Segment.Data.size();
11481148 Section.setMemoryOffset(Segment.Offset);
11491149 }
13071307 writeNameSection(Functions, Imports, NumFuncImports);
13081308 writeCodeRelocSection();
13091309 writeDataRelocSection();
1310 writeLinkingMetaDataSection(DataSegments, DataSize, DataAlignment,
1311 SymbolFlags, HasStackPointer, StackPointerGlobal);
1310 writeLinkingMetaDataSection(DataSegments, DataSize, SymbolFlags,
1311 HasStackPointer, StackPointerGlobal);
13121312
13131313 // TODO: Translate the .comment section to the output.
13141314 // TODO: Translate debug sections to the output.
192192
193193 WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
194194 : ObjectFile(Binary::ID_Wasm, Buffer) {
195 LinkingData.DataAlignment = 0;
196195 LinkingData.DataSize = 0;
197196
198197 ErrorAsOutParameter ErrAsOutParam(&Err);
384383 case wasm::WASM_DATA_SIZE:
385384 LinkingData.DataSize = readVaruint32(Ptr);
386385 break;
387 case wasm::WASM_DATA_ALIGNMENT:
388 LinkingData.DataAlignment = readVaruint32(Ptr);
389 break;
390 case wasm::WASM_SEGMENT_NAMES: {
386 case wasm::WASM_SEGMENT_INFO: {
391387 uint32_t Count = readVaruint32(Ptr);
392388 if (Count > DataSegments.size())
393389 return make_error("Too many segment names",
394390 object_error::parse_failed);
395 for (uint32_t i = 0; i < Count; i++)
391 for (uint32_t i = 0; i < Count; i++) {
396392 DataSegments[i].Data.Name = readString(Ptr);
393 DataSegments[i].Data.Alignment = readVaruint32(Ptr);
394 DataSegments[i].Data.Flags = readVaruint32(Ptr);
395 }
397396 break;
398397 }
399398 case wasm::WASM_STACK_POINTER:
733732 return Err;
734733 uint32_t Size = readVaruint32(Ptr);
735734 Segment.Data.Content = ArrayRef(Ptr, Size);
735 Segment.Data.Alignment = 0;
736 Segment.Data.Flags = 0;
736737 Segment.SectionOffset = Ptr - Start;
737738 Ptr += Size;
738739 DataSegments.push_back(Segment);
5757 commonSectionMapping(IO, Section);
5858 IO.mapRequired("Name", Section.Name);
5959 IO.mapRequired("DataSize", Section.DataSize);
60 IO.mapRequired("DataAlignment", Section.DataAlignment);
6160 IO.mapOptional("SymbolInfo", Section.SymbolInfos);
62 IO.mapOptional("SegmentNames", Section.SegmentNames);
61 IO.mapOptional("SegmentInfo", Section.SegmentInfos);
6362 }
6463
6564 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
265264 IO.mapRequired("Name", NameEntry.Name);
266265 }
267266
267 void MappingTraits::mapping(
268 IO &IO, WasmYAML::SegmentInfo &SegmentInfo) {
269 IO.mapRequired("Index", SegmentInfo.Index);
270 IO.mapRequired("Name", SegmentInfo.Name);
271 IO.mapRequired("Alignment", SegmentInfo.Alignment);
272 IO.mapRequired("Flags", SegmentInfo.Flags);
273 }
274
268275 void MappingTraits::mapping(
269276 IO &IO, WasmYAML::LocalDecl &LocalDecl) {
270277 IO.mapRequired("Type", LocalDecl.Type);
1414 ; CHECK: - Type: CUSTOM
1515 ; CHECK-NEXT: Name: linking
1616 ; CHECK-NEXT: DataSize: 2
17 ; CHECK-NEXT: DataAlignment: 1
18 ; CHECK-NEXT: SegmentNames:
17 ; CHECK-NEXT: SegmentInfo:
1918 ; CHECK-NEXT: - Index: 0
2019 ; CHECK-NEXT: Name: .data
20 ; CHECK-NEXT: Alignment: 1
21 ; CHECK-NEXT: Flags: 0
2122 ; CHECK-NEXT: ...
1212 ; CHECK-NEXT: - Type: CUSTOM
1313 ; CHECK-NEXT: Name: linking
1414 ; CHECK-NEXT: DataSize: 4
15 ; CHECK-NEXT: DataAlignment: 4
16 ; CHECK-NEXT: SegmentNames:
15 ; CHECK-NEXT: SegmentInfo:
1716 ; CHECK-NEXT: - Index: 0
1817 ; CHECK-NEXT: Name: .bss.g0
18 ; CHECK-NEXT: Alignment: 4
19 ; CHECK-NEXT: Flags: 0
1920 ; CHECK-NEXT: ...
6666 ; CHECK: - Type: CUSTOM
6767 ; CHECK-NEXT: Name: linking
6868 ; CHECK-NEXT: DataSize: 28
69 ; CHECK-NEXT: DataAlignment: 8
70 ; CHECK-NEXT: SegmentNames:
69 ; CHECK-NEXT: SegmentInfo:
7170 ; CHECK-NEXT: - Index: 0
7271 ; CHECK-NEXT: Name: .data.global0
72 ; CHECK-NEXT: Alignment: 8
73 ; CHECK-NEXT: Flags: 0
7374 ; CHECK-NEXT: - Index: 1
7475 ; CHECK-NEXT: Name: .sec1
76 ; CHECK-NEXT: Alignment: 8
77 ; CHECK-NEXT: Flags: 0
7578 ; CHECK-NEXT: - Index: 2
7679 ; CHECK-NEXT: Name: .sec2
80 ; CHECK-NEXT: Alignment: 8
81 ; CHECK-NEXT: Flags: 0
7782 ; CHECK-NEXT: ...
7878 ; CHECK-NEXT: - Type: CUSTOM
7979 ; CHECK-NEXT: Name: linking
8080 ; CHECK-NEXT: DataSize: 28
81 ; CHECK-NEXT: DataAlignment: 8
8281 ; CHECK-NEXT: SymbolInfo:
8382 ; CHECK-NEXT: - Name: .L.str1
8483 ; CHECK-NEXT: Flags: 2
8584 ; CHECK-NEXT: - Name: .L.str2
8685 ; CHECK-NEXT: Flags: 2
87 ; CHECK-NEXT: SegmentNames:
86 ; CHECK-NEXT: SegmentInfo:
8887 ; CHECK-NEXT: - Index: 0
8988 ; CHECK-NEXT: Name: .rodata..L.str1
89 ; CHECK-NEXT: Alignment: 1
90 ; CHECK-NEXT: Flags: 0
9091 ; CHECK-NEXT: - Index: 1
9192 ; CHECK-NEXT: Name: .rodata..L.str2
93 ; CHECK-NEXT: Alignment: 1
94 ; CHECK-NEXT: Flags: 0
9295 ; CHECK-NEXT: - Index: 2
9396 ; CHECK-NEXT: Name: .data.a
97 ; CHECK-NEXT: Alignment: 8
98 ; CHECK-NEXT: Flags: 0
9499 ; CHECK-NEXT: - Index: 3
95100 ; CHECK-NEXT: Name: .data.b
101 ; CHECK-NEXT: Alignment: 8
102 ; CHECK-NEXT: Flags: 0
96103 ; CHECK_NEXT: ...
100100 ; CHECK-NEXT: - Type: CUSTOM
101101 ; CHECK-NEXT: Name: linking
102102 ; CHECK-NEXT: DataSize: 12
103 ; CHECK-NEXT: DataAlignment: 8
104103 ; CHECK-NEXT: SymbolInfo:
105104 ; CHECK-NEXT: - Name: foo_alias
106105 ; CHECK-NEXT: Flags: 1
107106 ; CHECK-NEXT: - Name: bar_alias
108107 ; CHECK-NEXT: Flags: 1
109 ; CHECK-NEXT: SegmentNames:
108 ; CHECK-NEXT: SegmentInfo:
110109 ; CHECK-NEXT: - Index: 0
111110 ; CHECK-NEXT: Name: .data.bar
111 ; CHECK-NEXT: Alignment: 8
112 ; CHECK-NEXT: Flags: 0
112113 ; CHECK-NEXT: - Index: 1
113114 ; CHECK-NEXT: Name: .data.bar_alias_address
115 ; CHECK-NEXT: Alignment: 8
116 ; CHECK-NEXT: Flags: 0
114117 ; CHECK-NEXT: ...
115118
116119 ; CHECK-SYMS: SYMBOL TABLE:
2626 ; CHECK-NEXT: - Type: CUSTOM
2727 ; CHECK-NEXT: Name: linking
2828 ; CHECK-NEXT: DataSize: 0
29 ; CHECK-NEXT: DataAlignment: 0
3029 ; CHECK-NEXT: SymbolInfo:
3130 ; CHECK-NEXT: - Name: weak_external_data
3231 ; CHECK-NEXT: Flags: 1
2626 - Type: CUSTOM
2727 Name: linking
2828 DataSize: 10
29 DataAlignment: 2
3029 SymbolInfo:
3130 - Name: function_export
3231 Flags: 1
4847 # CHECK: - Type: CUSTOM
4948 # CHECK: Name: linking
5049 # CHECK: DataSize: 10
51 # CHECK: DataAlignment: 2
5250 # CHECK: SymbolInfo:
5351 # CHECK: - Name: function_export
5452 # CHECK: Flags: 1
5252 - Type: CUSTOM
5353 Name: "linking"
5454 DataSize: 0
55 DataAlignment: 0
5655
5756 # CHECK: 00000400 D bar
5857 # CHECK-NEXT: U fimport
2222 - Type: CUSTOM
2323 Name: "linking"
2424 DataSize: 0
25 DataAlignment: 0
2625
2726 # CHECK: U bar
2827 # CHECK: U foo
5252 - Type: CUSTOM
5353 Name: linking
5454 DataSize: 0
55 DataAlignment: 2
5655 SymbolInfo:
5756 - Name: weak_global_func
5857 Flags: 1
567567 WASM-NEXT: Offset: 257
568568 WASM-NEXT: Name: linking
569569 WASM-NEXT: DataSize: 13
570 WASM-NEXT: DataAlignment: 1
571570 WASM-NEXT: }
572571 WASM-NEXT: ]
155155 if (WasmSec.Name == "linking") {
156156 const wasm::WasmLinkingData &LinkingData = Obj->linkingData();
157157 W.printNumber("DataSize", LinkingData.DataSize);
158 if (LinkingData.DataAlignment)
159 W.printNumber("DataAlignment", LinkingData.DataAlignment);
160158 }
161159 break;
162160 case wasm::WASM_SEC_DATA: {
6767 size_t Index = 0;
6868 for (const object::WasmSegment &Segment : Obj.dataSegments()) {
6969 if (!Segment.Data.Name.empty()) {
70 WasmYAML::NameEntry NameEntry;
71 NameEntry.Name = Segment.Data.Name;
72 NameEntry.Index = Index;
73 LinkingSec->SegmentNames.push_back(NameEntry);
70 WasmYAML::SegmentInfo SegmentInfo;
71 SegmentInfo.Name = Segment.Data.Name;
72 SegmentInfo.Index = Index;
73 SegmentInfo.Alignment = Segment.Data.Alignment;
74 SegmentInfo.Flags = Segment.Data.Flags;
75 LinkingSec->SegmentInfos.push_back(SegmentInfo);
7476 }
7577 Index++;
7678 }
8284 }
8385 }
8486 LinkingSec->DataSize = Obj.linkingData().DataSize;
85 LinkingSec->DataAlignment = Obj.linkingData().DataAlignment;
8687 CustomSec = std::move(LinkingSec);
8788 } else {
8889 CustomSec = make_unique(WasmSec.Name);
139139 encodeULEB128(Section.DataSize, SubSection.GetStream());
140140 SubSection.Done();
141141
142 // DATA_ALIGNMENT subsection
143 encodeULEB128(wasm::WASM_DATA_ALIGNMENT, OS);
144 encodeULEB128(Section.DataAlignment, SubSection.GetStream());
145 SubSection.Done();
146
147142 // SYMBOL_INFO subsection
148143 if (Section.SymbolInfos.size()) {
149144 encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
158153 }
159154
160155 // SEGMENT_NAMES subsection
161 if (Section.SegmentNames.size()) {
162 encodeULEB128(wasm::WASM_SEGMENT_NAMES, OS);
163 encodeULEB128(Section.SegmentNames.size(), SubSection.GetStream());
164 for (const WasmYAML::NameEntry &NameEntry : Section.SegmentNames) {
165 encodeULEB128(NameEntry.Index, SubSection.GetStream());
166 writeStringRef(NameEntry.Name, SubSection.GetStream());
156 if (Section.SegmentInfos.size()) {
157 encodeULEB128(wasm::WASM_SEGMENT_INFO, OS);
158 encodeULEB128(Section.SegmentInfos.size(), SubSection.GetStream());
159 for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) {
160 encodeULEB128(SegmentInfo.Index, SubSection.GetStream());
161 writeStringRef(SegmentInfo.Name, SubSection.GetStream());
162 encodeULEB128(SegmentInfo.Alignment, SubSection.GetStream());
163 encodeULEB128(SegmentInfo.Flags, SubSection.GetStream());
167164 }
168165 SubSection.Done();
169166 }