llvm.org GIT mirror llvm / e5c4334
[WebAssembly] Add support for naming wasm data segments Add adds support for naming data segments. This is useful useful linkers so that they can merge similar sections. Differential Revision: https://reviews.llvm.org/D37886 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313692 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 2 years ago
14 changed file(s) with 128 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
9696 uint32_t MemoryIndex;
9797 WasmInitExpr Offset;
9898 ArrayRef Content;
99 StringRef Name;
99100 };
100101
101102 struct WasmElemSegment {
183184 WASM_SYMBOL_INFO = 0x2,
184185 WASM_DATA_SIZE = 0x3,
185186 WASM_DATA_ALIGNMENT = 0x4,
187 WASM_SEGMENT_NAMES = 0x5,
186188 };
187189
188190 enum : unsigned {
159159 return C && C->Name == "linking";
160160 }
161161
162 std::vector SymbolInfos;
163162 uint32_t DataSize;
164163 uint32_t DataAlignment;
164 std::vector SymbolInfos;
165 std::vector SegmentNames;
165166 };
166167
167168 struct TypeSection : Section {
101101 // wasm data segment.
102102 struct WasmDataSegment {
103103 MCSectionWasm *Section;
104 StringRef Name;
104105 uint32_t Offset;
105106 SmallVector Data;
106107 };
278279 uint32_t NumFuncImports);
279280 void writeCodeRelocSection();
280281 void writeDataRelocSection();
281 void writeLinkingMetaDataSection(uint32_t DataSize, uint32_t DataAlignment,
282 void writeLinkingMetaDataSection(ArrayRef Segments,
283 uint32_t DataSize, uint32_t DataAlignment,
282284 ArrayRef WeakSymbols,
283285 bool HasStackPointer,
284286 uint32_t StackPointerGlobal);
910912 }
911913
912914 void WasmObjectWriter::writeLinkingMetaDataSection(
913 uint32_t DataSize, uint32_t DataAlignment, ArrayRef WeakSymbols,
915 ArrayRef Segments, uint32_t DataSize,
916 uint32_t DataAlignment, ArrayRef WeakSymbols,
914917 bool HasStackPointer, uint32_t StackPointerGlobal) {
915918 SectionBookkeeping Section;
916919 startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
939942
940943 startSection(SubSection, wasm::WASM_DATA_ALIGNMENT);
941944 encodeULEB128(DataAlignment, getStream());
945 endSection(SubSection);
946 }
947
948 if (Segments.size()) {
949 startSection(SubSection, wasm::WASM_SEGMENT_NAMES);
950 encodeULEB128(Segments.size(), getStream());
951 for (const WasmDataSegment &Segment : Segments)
952 writeString(Segment.Name);
942953 endSection(SubSection);
943954 }
944955
11281139 DataSize = alignTo(DataSize, Section.getAlignment());
11291140 DataSegments.emplace_back();
11301141 WasmDataSegment &Segment = DataSegments.back();
1142 Segment.Name = Section.getSectionName();
11311143 Segment.Offset = DataSize;
11321144 Segment.Section = &Section;
11331145 addData(Segment.Data, Section, DataAlignment);
12871299 writeNameSection(Functions, Imports, NumFuncImports);
12881300 writeCodeRelocSection();
12891301 writeDataRelocSection();
1290 writeLinkingMetaDataSection(DataSize, DataAlignment, WeakSymbols, HasStackPointer, StackPointerGlobal);
1302 writeLinkingMetaDataSection(DataSegments, DataSize, DataAlignment,
1303 WeakSymbols, HasStackPointer, StackPointerGlobal);
12911304
12921305 // TODO: Translate the .comment section to the output.
12931306 // TODO: Translate debug sections to the output.
395395 case wasm::WASM_DATA_ALIGNMENT:
396396 LinkingData.DataAlignment = readVaruint32(Ptr);
397397 break;
398 case wasm::WASM_SEGMENT_NAMES: {
399 uint32_t Count = readVaruint32(Ptr);
400 if (Count > DataSegments.size())
401 return make_error("Too many segment names",
402 object_error::parse_failed);
403 for (uint32_t i = 0; i < Count; i++)
404 DataSegments[i].Data.Name = readString(Ptr);
405 break;
406 }
398407 case wasm::WASM_STACK_POINTER:
399408 default:
400409 Ptr += Size;
5959 IO.mapRequired("DataSize", Section.DataSize);
6060 IO.mapRequired("DataAlignment", Section.DataAlignment);
6161 IO.mapOptional("SymbolInfo", Section.SymbolInfos);
62 IO.mapOptional("SegmentNames", Section.SegmentNames);
6263 }
6364
6465 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
88
99 @gBd = hidden global [2 x %struct.bd] [%struct.bd { i8 1 }, %struct.bd { i8 2 }], align 1
1010
11 ; CHECK: - Type: DATA
12 ; CHECK: Content: '0102'
13 ; CHECK: DataSize: 2
11 ; CHECK: - Type: DATA
12 ; CHECK: Content: '0102'
13
14 ; CHECK: - Type: CUSTOM
15 ; CHECK-NEXT: Name: linking
16 ; CHECK-NEXT: DataSize: 2
17 ; CHECK-NEXT: DataAlignment: 1
18 ; CHECK-NEXT: SegmentNames:
19 ; CHECK-NEXT: - Index: 0
20 ; CHECK-NEXT: Name: .data
21 ; CHECK-NEXT: ...
0 ; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s
1
2 @g0 = global i8* null, align 4
3
4 ; CHECK: - Type: DATA
5 ; CHECK-NEXT: Segments:
6 ; CHECK-NEXT: - SectionOffset: 6
7 ; CHECK-NEXT: MemoryIndex: 0
8 ; CHECK-NEXT: Offset:
9 ; CHECK-NEXT: Opcode: I32_CONST
10 ; CHECK-NEXT: Value: 0
11 ; CHECK-NEXT: Content: '00000000'
12 ; CHECK-NEXT: - Type: CUSTOM
13 ; CHECK-NEXT: Name: linking
14 ; CHECK-NEXT: DataSize: 4
15 ; CHECK-NEXT: DataAlignment: 4
16 ; CHECK-NEXT: SegmentNames:
17 ; CHECK-NEXT: - Index: 0
18 ; CHECK-NEXT: Name: .bss.g0
19 ; CHECK-NEXT: ...
6262 ; CHECK-NEXT: Opcode: I32_CONST
6363 ; CHECK-NEXT: Value: 24
6464 ; CHECK-NEXT: Content: '08000000'
65
66 ; CHECK: - Type: CUSTOM
67 ; CHECK-NEXT: Name: linking
68 ; CHECK-NEXT: DataSize: 28
69 ; CHECK-NEXT: DataAlignment: 8
70 ; CHECK-NEXT: SegmentNames:
71 ; CHECK-NEXT: - Index: 0
72 ; CHECK-NEXT: Name: .data.global0
73 ; CHECK-NEXT: - Index: 1
74 ; CHECK-NEXT: Name: .sec1
75 ; CHECK-NEXT: - Index: 2
76 ; CHECK-NEXT: Name: .sec2
77 ; CHECK-NEXT: ...
7373 ; CHECK-NEXT: Name: linking
7474 ; CHECK-NEXT: DataSize: 28
7575 ; CHECK-NEXT: DataAlignment: 8
76 ; CHECK-NEXT: SegmentNames:
77 ; CHECK-NEXT: - Index: 0
78 ; CHECK-NEXT: Name: .rodata..L.str1
79 ; CHECK-NEXT: - Index: 1
80 ; CHECK-NEXT: Name: .rodata..L.str2
81 ; CHECK-NEXT: - Index: 2
82 ; CHECK-NEXT: Name: .data.a
83 ; CHECK-NEXT: - Index: 3
84 ; CHECK-NEXT: Name: .data.b
7685 ; CHECK-NEXT: ...
100100 ; CHECK-NEXT: Flags: 1
101101 ; CHECK-NEXT: - Name: bar_alias
102102 ; CHECK-NEXT: Flags: 1
103 ; CHECK-NEXT: SegmentNames:
104 ; CHECK-NEXT: - Index: 0
105 ; CHECK-NEXT: Name: .data.bar
106 ; CHECK-NEXT: - Index: 1
107 ; CHECK-NEXT: Name: .data.bar_alias_address
103108 ; CHECK-NEXT: ...
542542 WASM-NEXT: Type: DATA (0xB)
543543 WASM-NEXT: Size: 19
544544 WASM-NEXT: Offset: 154
545 WASM-NEXT: Segments [
546 WASM-NEXT: Segment {
547 WASM-NEXT: Size: 13
548 WASM-NEXT: Offset: 0
549 WASM-NEXT: }
550 WASM-NEXT: ]
545551 WASM-NEXT: }
546552 WASM-NEXT: Section {
547553 WASM-NEXT: Type: CUSTOM (0x0)
159159 W.printNumber("DataAlignment", LinkingData.DataAlignment);
160160 }
161161 break;
162 case wasm::WASM_SEC_DATA: {
163 ListScope Group(W, "Segments");
164 for (const WasmSegment &Segment : Obj->dataSegments()) {
165 DictScope Group(W, "Segment");
166 if (!Segment.Data.Name.empty())
167 W.printString("Name", Segment.Data.Name);
168 W.printNumber("Size", Segment.Data.Content.size());
169 if (Segment.Data.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST)
170 W.printNumber("Offset", Segment.Data.Offset.Value.Int32);
171 }
172 break;
173 }
162174 case wasm::WASM_SEC_MEMORY:
163175 ListScope Group(W, "Memories");
164176 for (const wasm::WasmLimits &Memory : Obj->memories()) {
6969 CustomSec = std::move(NameSec);
7070 } else if (WasmSec.Name == "linking") {
7171 std::unique_ptr LinkingSec = make_unique();
72 size_t Index = 0;
73 for (const object::WasmSegment &Segment : Obj.dataSegments()) {
74 if (!Segment.Data.Name.empty()) {
75 WasmYAML::NameEntry NameEntry;
76 NameEntry.Name = Segment.Data.Name;
77 NameEntry.Index = Index;
78 LinkingSec->SegmentNames.push_back(NameEntry);
79 }
80 Index++;
81 }
7282 for (const object::SymbolRef& Sym: Obj.symbols()) {
7383 const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
7484 if (Symbol.Flags != 0) {
233243 }
234244 case wasm::WASM_SEC_DATA: {
235245 auto DataSec = make_unique();
236 for (auto &Segment : Obj.dataSegments()) {
246 for (const object::WasmSegment &Segment : Obj.dataSegments()) {
237247 WasmYAML::DataSegment Seg;
238248 Seg.SectionOffset = Segment.SectionOffset;
239249 Seg.MemoryIndex = Segment.Data.MemoryIndex;
156156
157157 SubSection.Done();
158158 }
159
160 // 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());
167 }
168 SubSection.Done();
169 }
159170 return 0;
160171 }
161172