llvm.org GIT mirror llvm / e1acb56
[WebAssembly] Add support for init functions linking metadata Summary: This change lays the groundwork lowering of @llvm.global_ctors and @llvm.global_dtors for the wasm object format. Some parts of this patch are subset of: https://reviews.llvm.org/D40759 See https://github.com/WebAssembly/tool-conventions/issues/25 Subscribers: jfb, dschuff, jgravelle-google, aheejin, sunfish Differential Revision: https://reviews.llvm.org/D41208 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320742 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 9 months ago
8 changed file(s) with 69 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
114114 int64_t Addend; // A value to add to the symbol.
115115 };
116116
117 struct WasmInitFunc {
118 uint32_t Priority;
119 uint32_t FunctionIndex;
120 };
121
117122 struct WasmLinkingData {
118123 uint32_t DataSize;
124 std::vector InitFunctions;
119125 };
120126
121127 enum : unsigned {
184190 WASM_SYMBOL_INFO = 0x2,
185191 WASM_DATA_SIZE = 0x3,
186192 WASM_SEGMENT_INFO = 0x5,
193 WASM_INIT_FUNCS = 0x6,
187194 };
188195
189196 const unsigned WASM_SYMBOL_BINDING_MASK = 0x3;
205205 bool isRelocatableObject() const override;
206206
207207 private:
208 bool isValidFunctionIndex(uint32_t Index) const;
208209 const WasmSection &getWasmSection(DataRefImpl Ref) const;
209210 const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
210211
130130 SymbolFlags Flags;
131131 };
132132
133 struct InitFunction {
134 uint32_t Priority;
135 uint32_t FunctionIndex;
136 };
137
133138 struct Section {
134139 explicit Section(SectionType SecType) : Type(SecType) {}
135140 virtual ~Section();
172177 uint32_t DataSize;
173178 std::vector SymbolInfos;
174179 std::vector SegmentInfos;
180 std::vector InitFunctions;
175181 };
176182
177183 struct TypeSection : Section {
308314 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::NameEntry)
309315 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SegmentInfo)
310316 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::SymbolInfo)
317 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::WasmYAML::InitFunction)
311318
312319 namespace llvm {
313320 namespace yaml {
400407 static void mapping(IO &IO, WasmYAML::SymbolInfo &Info);
401408 };
402409
410 template <> struct MappingTraits {
411 static void mapping(IO &IO, WasmYAML::InitFunction &Init);
412 };
413
403414 template <> struct ScalarEnumerationTraits {
404415 static void enumeration(IO &IO, WasmYAML::ValueType &Type);
405416 };
397397 }
398398 break;
399399 }
400 case wasm::WASM_INIT_FUNCS: {
401 uint32_t Count = readVaruint32(Ptr);
402 LinkingData.InitFunctions.reserve(Count);
403 for (uint32_t i = 0; i < Count; i++) {
404 wasm::WasmInitFunc Init;
405 Init.Priority = readVaruint32(Ptr);
406 Init.FunctionIndex = readVaruint32(Ptr);
407 if (!isValidFunctionIndex(Init.FunctionIndex))
408 return make_error("Invalid function index: " +
409 Twine(Init.FunctionIndex),
410 object_error::parse_failed);
411 LinkingData.InitFunctions.emplace_back(Init);
412 }
413 break;
414 }
400415 default:
401416 Ptr += Size;
402417 break;
655670 return Error::success();
656671 }
657672
673 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
674 return Index < FunctionTypes.size() + NumImportedFunctions;
675 }
676
658677 Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
659678 StartFunction = readVaruint32(Ptr);
660 if (StartFunction >= FunctionTypes.size())
679 if (!isValidFunctionIndex(StartFunction))
661680 return make_error("Invalid start function",
662681 object_error::parse_failed);
663682 return Error::success();
5959 IO.mapRequired("DataSize", Section.DataSize);
6060 IO.mapOptional("SymbolInfo", Section.SymbolInfos);
6161 IO.mapOptional("SegmentInfo", Section.SegmentInfos);
62 IO.mapOptional("InitFunctions", Section.InitFunctions);
6263 }
6364
6465 static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) {
358359 IO.mapRequired("Content", Segment.Content);
359360 }
360361
362 void MappingTraits::mapping(
363 IO &IO, WasmYAML::InitFunction &Init) {
364 IO.mapRequired("Priority", Init.Priority);
365 IO.mapRequired("FunctionIndex", Init.FunctionIndex);
366 }
367
361368 void MappingTraits::mapping(IO &IO,
362369 WasmYAML::SymbolInfo &Info) {
363370 IO.mapRequired("Name", Info.Name);
4040 Alignment: 2
4141 Flags: [ ]
4242 Name: moredata
43 InitFunctions:
44 - Priority: 1
45 FunctionIndex: 0
4346 ...
4447 # CHECK: - Type: CUSTOM
4548 # CHECK-NEXT: Name: linking
5659 # CHECK-NEXT: Name: moredata
5760 # CHECK-NEXT: Alignment: 2
5861 # CHECK-NEXT: Flags: [ ]
62 # CHECK-NEXT: InitFunctions:
63 # CHECK-NEXT: - Priority: 1
64 # CHECK-NEXT: FunctionIndex: 0
5965 # CHECK-NEXT: ...
7979 for (const object::SymbolRef& Sym: Obj.symbols()) {
8080 const object::WasmSymbol Symbol = Obj.getWasmSymbol(Sym);
8181 if (Symbol.Flags != 0) {
82 WasmYAML::SymbolInfo Info = { Symbol.Name, Symbol.Flags };
83 LinkingSec->SymbolInfos.push_back(Info);
82 WasmYAML::SymbolInfo Info{Symbol.Name, Symbol.Flags};
83 LinkingSec->SymbolInfos.emplace_back(Info);
8484 }
8585 }
8686 LinkingSec->DataSize = Obj.linkingData().DataSize;
87 for (const wasm::WasmInitFunc &Func : Obj.linkingData().InitFunctions) {
88 WasmYAML::InitFunction F{Func.Priority, Func.FunctionIndex};
89 LinkingSec->InitFunctions.emplace_back(F);
90 }
8791 CustomSec = std::move(LinkingSec);
8892 } else {
8993 CustomSec = make_unique(WasmSec.Name);
161161 }
162162 SubSection.Done();
163163 }
164
165 // INIT_FUNCS subsection
166 if (Section.InitFunctions.size()) {
167 encodeULEB128(wasm::WASM_INIT_FUNCS, OS);
168 encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
169 for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
170 encodeULEB128(Func.Priority, SubSection.GetStream());
171 encodeULEB128(Func.FunctionIndex, SubSection.GetStream());
172 }
173 SubSection.Done();
174 }
164175 return 0;
165176 }
166177