llvm.org GIT mirror llvm / 49ab5d5
[WebAssembly] Add data size and alignement to linking section The overal size of the data section (including BSS) is otherwise not included in the wasm binary. Differential Revision: https://reviews.llvm.org/D34657 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306459 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 2 years ago
13 changed file(s) with 171 addition(s) and 80 deletion(s). Raw diff Collapse all Expand all
109109 int32_t Index; // Index into function to global index space.
110110 uint64_t Offset; // Offset from the start of the section.
111111 int64_t Addend; // A value to add to the symbol.
112 };
113
114 struct WasmLinkingData {
115 uint32_t DataSize;
116 uint32_t DataAlignment;
112117 };
113118
114119 enum : unsigned {
174179
175180 // Linking metadata kinds.
176181 enum : unsigned {
177 WASM_STACK_POINTER = 0x1,
178 WASM_SYMBOL_INFO = 0x2,
182 WASM_STACK_POINTER = 0x1,
183 WASM_SYMBOL_INFO = 0x2,
184 WASM_DATA_SIZE = 0x3,
185 WASM_DATA_ALIGNMENT = 0x4,
179186 };
180187
181188 enum : unsigned {
9999 const std::vector& memories() const { return Memories; }
100100 const std::vector& globals() const { return Globals; }
101101 const std::vector& exports() const { return Exports; }
102 const wasm::WasmLinkingData& linkingData() const { return LinkingData; }
102103
103104 uint32_t getNumberOfSymbols() const {
104105 return Symbols.size();
213214 std::vector Symbols;
214215 ArrayRef CodeSection;
215216 uint32_t StartFunction = -1;
217 wasm::WasmLinkingData LinkingData;
216218
217219 StringMap SymbolMap;
218220 };
153153 }
154154
155155 std::vector SymbolInfos;
156 uint32_t DataSize;
157 uint32_t DataAlignment;
156158 };
157159
158160 struct TypeSection : Section {
264264 uint32_t NumFuncImports);
265265 void writeCodeRelocSection();
266266 void writeDataRelocSection(uint64_t DataSectionHeaderSize);
267 void writeLinkingMetaDataSection(ArrayRef WeakSymbols,
267 void writeLinkingMetaDataSection(uint32_t DataSize, uint32_t DataAlignment,
268 ArrayRef WeakSymbols,
268269 bool HasStackPointer,
269270 uint32_t StackPointerGlobal);
270271
876877 }
877878
878879 void WasmObjectWriter::writeLinkingMetaDataSection(
879 ArrayRef WeakSymbols, bool HasStackPointer,
880 uint32_t StackPointerGlobal) {
881 if (!HasStackPointer && WeakSymbols.empty())
882 return;
883
880 uint32_t DataSize, uint32_t DataAlignment, ArrayRef WeakSymbols,
881 bool HasStackPointer, uint32_t StackPointerGlobal) {
884882 SectionBookkeeping Section;
885883 startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
886884 SectionBookkeeping SubSection;
898896 writeString(Export);
899897 encodeULEB128(wasm::WASM_SYMBOL_FLAG_WEAK, getStream());
900898 }
899 endSection(SubSection);
900 }
901
902 if (DataSize > 0) {
903 startSection(SubSection, wasm::WASM_DATA_SIZE);
904 encodeULEB128(DataSize, getStream());
905 endSection(SubSection);
906
907 startSection(SubSection, wasm::WASM_DATA_ALIGNMENT);
908 encodeULEB128(DataAlignment, getStream());
901909 endSection(SubSection);
902910 }
903911
922930 unsigned NumFuncImports = 0;
923931 unsigned NumGlobalImports = 0;
924932 SmallVector DataBytes;
933 uint32_t DataAlignment = 1;
925934 uint32_t StackPointerGlobal = 0;
926935 bool HasStackPointer = false;
927936
11561165 report_fatal_error("data sections must contain at most one variable");
11571166
11581167 DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
1168 DataAlignment = std::max(DataAlignment, DataSection.getAlignment());
11591169
11601170 DataSection.setSectionOffset(DataBytes.size());
11611171
12711281 writeNameSection(Functions, Imports, NumFuncImports);
12721282 writeCodeRelocSection();
12731283 writeDataRelocSection(DataSectionHeaderSize);
1274 writeLinkingMetaDataSection(WeakSymbols, HasStackPointer, StackPointerGlobal);
1284 writeLinkingMetaDataSection(DataBytes.size(), DataAlignment, WeakSymbols, HasStackPointer, StackPointerGlobal);
12751285
12761286 // TODO: Translate the .comment section to the output.
12771287 // 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;
196 LinkingData.DataSize = 0;
197
195198 ErrorAsOutParameter ErrAsOutParam(&Err);
196199 Header.Magic = getData().substr(0, 4);
197200 if (Header.Magic != StringRef("\0asm", 4)) {
304307 auto iter = SymbolMap.find(Symbol);
305308 if (iter == SymbolMap.end()) {
306309 return make_error(
307 "Invalid symbol name in linking section",
310 "Invalid symbol name in linking section: " + Symbol,
308311 object_error::parse_failed);
309312 }
310313 uint32_t SymIndex = iter->second;
317320 }
318321 break;
319322 }
323 case wasm::WASM_DATA_SIZE:
324 LinkingData.DataSize = readVaruint32(Ptr);
325 break;
326 case wasm::WASM_DATA_ALIGNMENT:
327 LinkingData.DataAlignment = readVaruint32(Ptr);
328 break;
320329 case wasm::WASM_STACK_POINTER:
321330 default:
322331 Ptr += Size;
5555 static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) {
5656 commonSectionMapping(IO, Section);
5757 IO.mapRequired("Name", Section.Name);
58 IO.mapRequired("DataSize", Section.DataSize);
59 IO.mapRequired("DataAlignment", Section.DataAlignment);
5860 IO.mapRequired("SymbolInfo", Section.SymbolInfos);
5961 }
6062
66 @b = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str2, i32 0, i32 0), align 8
77
88
9 ; CHECK: - Type: GLOBAL
10 ; CHECK: Globals:
11 ; CHECK: - Type: I32
12 ; CHECK: Mutable: false
13 ; CHECK: InitExpr:
14 ; CHECK: Opcode: I32_CONST
15 ; CHECK: Value: 0
16 ; CHECK: - Type: I32
17 ; CHECK: Mutable: false
18 ; CHECK: InitExpr:
19 ; CHECK: Opcode: I32_CONST
20 ; CHECK: Value: 6
21 ; CHECK: - Type: I32
22 ; CHECK: Mutable: false
23 ; CHECK: InitExpr:
24 ; CHECK: Opcode: I32_CONST
25 ; CHECK: Value: 16
26 ; CHECK: - Type: I32
27 ; CHECK: Mutable: false
28 ; CHECK: InitExpr:
29 ; CHECK: Opcode: I32_CONST
30 ; CHECK: Value: 24
31 ; CHECK: - Type: EXPORT
32 ; CHECK: Exports:
33 ; CHECK: - Name: a
34 ; CHECK: Kind: GLOBAL
35 ; CHECK: Index: 2
36 ; CHECK: - Name: b
37 ; CHECK: Kind: GLOBAL
38 ; CHECK: Index: 3
39 ; CHECK: - Type: DATA
40 ; CHECK: Relocations:
41 ; CHECK: - Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32
42 ; CHECK: Index: 0
43 ; CHECK: Offset: 0x00000016
44 ; CHECK: - Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32
45 ; CHECK: Index: 1
46 ; CHECK: Offset: 0x0000001E
47 ; CHECK: Segments:
48 ; CHECK: - Index: 0
49 ; CHECK: Offset:
50 ; CHECK: Opcode: I32_CONST
51 ; CHECK: Value: 0
52 ; CHECK: Content: 68656C6C6F00776F726C640000000000000000000000000006000000
9 ; CHECK: - Type: GLOBAL
10 ; CHECK-NEXT: Globals:
11 ; CHECK-NEXT: - Type: I32
12 ; CHECK-NEXT: Mutable: false
13 ; CHECK-NEXT: InitExpr:
14 ; CHECK-NEXT: Opcode: I32_CONST
15 ; CHECK-NEXT: Value: 0
16 ; CHECK-NEXT: - Type: I32
17 ; CHECK-NEXT: Mutable: false
18 ; CHECK-NEXT: InitExpr:
19 ; CHECK-NEXT: Opcode: I32_CONST
20 ; CHECK-NEXT: Value: 6
21 ; CHECK-NEXT: - Type: I32
22 ; CHECK-NEXT: Mutable: false
23 ; CHECK-NEXT: InitExpr:
24 ; CHECK-NEXT: Opcode: I32_CONST
25 ; CHECK-NEXT: Value: 16
26 ; CHECK-NEXT: - Type: I32
27 ; CHECK-NEXT: Mutable: false
28 ; CHECK-NEXT: InitExpr:
29 ; CHECK-NEXT: Opcode: I32_CONST
30 ; CHECK-NEXT: Value: 24
31 ; CHECK-NEXT: - Type: EXPORT
32 ; CHECK-NEXT: Exports:
33 ; CHECK-NEXT: - Name: a
34 ; CHECK-NEXT: Kind: GLOBAL
35 ; CHECK-NEXT: Index: 2
36 ; CHECK-NEXT: - Name: b
37 ; CHECK-NEXT: Kind: GLOBAL
38 ; CHECK-NEXT: Index: 3
39 ; CHECK-NEXT: - Type: DATA
40 ; CHECK-NEXT: Relocations:
41 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32
42 ; CHECK-NEXT: Index: 0
43 ; CHECK-NEXT: Offset: 0x00000016
44 ; CHECK-NEXT: - Type: R_WEBASSEMBLY_GLOBAL_ADDR_I32
45 ; CHECK-NEXT: Index: 1
46 ; CHECK-NEXT: Offset: 0x0000001E
47 ; CHECK-NEXT: Segments:
48 ; CHECK-NEXT: - Index: 0
49 ; CHECK-NEXT: Offset:
50 ; CHECK-NEXT: Opcode: I32_CONST
51 ; CHECK-NEXT: Value: 0
52 ; CHECK-NEXT: Content: 68656C6C6F00776F726C640000000000000000000000000006000000
53 ; CHECK-NEXT: - Type: CUSTOM
54 ; CHECK-NEXT: Name: linking
55 ; CHECK-NEXT: DataSize: 28
56 ; CHECK-NEXT: DataAlignment: 8
57 ; CHECK-NEXT: SymbolInfo:
58 ; CHECK-NEXT: ...
2626 ; CHECK-NEXT: Name: foo
2727 ; CHECK-NEXT: - Type: CUSTOM
2828 ; CHECK-NEXT: Name: linking
29 ; CHECK-NEXT: DataSize: 0
30 ; CHECK-NEXT: DataAlignment: 0
2931 ; CHECK-NEXT: SymbolInfo:
3032 ; CHECK-NEXT: - Name: foo_alias
3133 ; CHECK-NEXT: Flags: 1
2525 ; CHECK-NEXT: Name: weak_function
2626 ; CHECK-NEXT: - Type: CUSTOM
2727 ; CHECK-NEXT: Name: linking
28 ; CHECK-NEXT: DataSize: 0
29 ; CHECK-NEXT: DataAlignment: 0
2830 ; CHECK-NEXT: SymbolInfo:
2931 ; CHECK-NEXT: - Name: weak_external_data
3032 ; CHECK-NEXT: Flags: 1
22 FileHeader:
33 Version: 0x00000001
44 Sections:
5 - Type: TYPE
6 Signatures:
7 - ReturnType: I32
8 ParamTypes:
9 - Type: FUNCTION
10 FunctionTypes: [ 0, 0 ]
11 - Type: GLOBAL
12 Globals:
13 - Type: I32
14 Mutable: false
15 InitExpr:
16 Opcode: I32_CONST
17 Value: 1
518 - Type: EXPORT
619 Exports:
720 - Name: function_export
922 Index: 1
1023 - Name: global_export
1124 Kind: GLOBAL
12 Index: 2
25 Index: 0
1326 - Type: CUSTOM
1427 Name: linking
28 DataSize: 10
29 DataAlignment: 2
1530 SymbolInfo:
1631 - Name: function_export
1732 Flags: 1
2944 # CHECK: Index: 1
3045 # CHECK: - Name: global_export
3146 # CHECK: Kind: GLOBAL
32 # CHECK: Index: 2
47 # CHECK: Index: 0
3348 # CHECK: - Type: CUSTOM
3449 # CHECK: Name: linking
50 # CHECK: DataSize: 10
51 # CHECK: DataAlignment: 2
3552 # CHECK: SymbolInfo:
3653 # CHECK: - Name: function_export
3754 # CHECK: Flags: 1
3232 Index: 0x00000002
3333 - Type: CUSTOM
3434 Name: linking
35 DataSize: 0
36 DataAlignment: 2
3537 SymbolInfo:
3638 - Name: weak_global_func
3739 Flags: 1
7676 LinkingSec->SymbolInfos.push_back(Info);
7777 }
7878 }
79 LinkingSec->DataSize = Obj.linkingData().DataSize;
80 LinkingSec->DataAlignment = Obj.linkingData().DataAlignment;
7981 CustomSec = std::move(LinkingSec);
8082 } else {
8183 CustomSec = make_unique(WasmSec.Name);
109109 return 0;
110110 }
111111
112 int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
113 writeStringRef(Section.Name, OS);
114 if (Section.SymbolInfos.size()) {
115 encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
116 std::string OutString;
117 raw_string_ostream StringStream(OutString);
118
119 encodeULEB128(Section.SymbolInfos.size(), StringStream);
120 for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
121 writeStringRef(Info.Name, StringStream);
122 encodeULEB128(Info.Flags, StringStream);
123 }
124
112 class SubSectionWriter {
113 raw_ostream &OS;
114 std::string OutString;
115 raw_string_ostream StringStream;
116
117 public:
118 SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {}
119
120 void Done() {
125121 StringStream.flush();
126122 encodeULEB128(OutString.size(), OS);
127123 OS << OutString;
124 OutString.clear();
125 }
126
127 raw_ostream& GetStream() {
128 return StringStream;
129 }
130 };
131
132 int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section) {
133 writeStringRef(Section.Name, OS);
134
135 SubSectionWriter SubSection(OS);
136
137 // DATA_SIZE subsection
138 encodeULEB128(wasm::WASM_DATA_SIZE, OS);
139 encodeULEB128(Section.DataSize, SubSection.GetStream());
140 SubSection.Done();
141
142 // DATA_ALIGNMENT subsection
143 encodeULEB128(wasm::WASM_DATA_ALIGNMENT, OS);
144 encodeULEB128(Section.DataAlignment, SubSection.GetStream());
145 SubSection.Done();
146
147 // SYMBOL_INFO subsection
148 if (Section.SymbolInfos.size()) {
149 encodeULEB128(wasm::WASM_SYMBOL_INFO, OS);
150
151 encodeULEB128(Section.SymbolInfos.size(), SubSection.GetStream());
152 for (const WasmYAML::SymbolInfo &Info : Section.SymbolInfos) {
153 writeStringRef(Info.Name, SubSection.GetStream());
154 encodeULEB128(Info.Flags, SubSection.GetStream());
155 }
156
157 SubSection.Done();
128158 }
129159 return 0;
130160 }
133163 writeStringRef(Section.Name, OS);
134164 if (Section.FunctionNames.size()) {
135165 encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS);
136 std::string OutString;
137 raw_string_ostream StringStream(OutString);
138
139 encodeULEB128(Section.FunctionNames.size(), StringStream);
166
167 SubSectionWriter SubSection(OS);
168
169 encodeULEB128(Section.FunctionNames.size(), SubSection.GetStream());
140170 for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) {
141 encodeULEB128(NameEntry.Index, StringStream);
142 writeStringRef(NameEntry.Name, StringStream);
143 }
144
145 StringStream.flush();
146 encodeULEB128(OutString.size(), OS);
147 OS << OutString;
171 encodeULEB128(NameEntry.Index, SubSection.GetStream());
172 writeStringRef(NameEntry.Name, SubSection.GetStream());
173 }
174
175 SubSection.Done();
148176 }
149177 return 0;
150178 }