]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Object/WasmObjectFile.cpp
MFV r319950: 5220 L2ARC does not support devices that do not provide 512B access
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Object / WasmObjectFile.cpp
1 //===- WasmObjectFile.cpp - Wasm object file implementation -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Object/Wasm.h"
11 #include "llvm/Support/Endian.h"
12 #include "llvm/Support/LEB128.h"
13
14 namespace llvm {
15 namespace object {
16
17 Expected<std::unique_ptr<WasmObjectFile>>
18 ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
19   Error Err = Error::success();
20   auto ObjectFile = llvm::make_unique<WasmObjectFile>(Buffer, Err);
21   if (Err)
22     return std::move(Err);
23
24   return std::move(ObjectFile);
25 }
26
27 namespace {
28
29 uint32_t readUint32(const uint8_t *&Ptr) {
30   uint32_t Result = support::endian::read32le(Ptr);
31   Ptr += sizeof(Result);
32   return Result;
33 }
34
35 uint64_t readULEB128(const uint8_t *&Ptr) {
36   unsigned Count;
37   uint64_t Result = decodeULEB128(Ptr, &Count);
38   Ptr += Count;
39   return Result;
40 }
41
42 StringRef readString(const uint8_t *&Ptr) {
43   uint32_t StringLen = readULEB128(Ptr);
44   StringRef Return = StringRef(reinterpret_cast<const char *>(Ptr), StringLen);
45   Ptr += StringLen;
46   return Return;
47 }
48
49 Error readSection(wasm::WasmSection &Section, const uint8_t *&Ptr,
50                   const uint8_t *Start) {
51   // TODO(sbc): Avoid reading past EOF in the case of malformed files.
52   Section.Offset = Ptr - Start;
53   Section.Type = readULEB128(Ptr);
54   uint32_t Size = readULEB128(Ptr);
55   if (Size == 0)
56     return make_error<StringError>("Zero length section",
57                                    object_error::parse_failed);
58   Section.Content = ArrayRef<uint8_t>(Ptr, Size);
59   Ptr += Size;
60   return Error::success();
61 }
62 }
63
64 WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
65     : ObjectFile(Binary::ID_Wasm, Buffer) {
66   ErrorAsOutParameter ErrAsOutParam(&Err);
67   Header.Magic = getData().substr(0, 4);
68   if (Header.Magic != StringRef("\0asm", 4)) {
69     Err = make_error<StringError>("Bad magic number",
70                                   object_error::parse_failed);
71     return;
72   }
73   const uint8_t *Ptr = getPtr(4);
74   Header.Version = readUint32(Ptr);
75   if (Header.Version != wasm::WasmVersion) {
76     Err = make_error<StringError>("Bad version number",
77                                   object_error::parse_failed);
78     return;
79   }
80
81   const uint8_t *Eof = getPtr(getData().size());
82   wasm::WasmSection Sec;
83   while (Ptr < Eof) {
84     if ((Err = readSection(Sec, Ptr, getPtr(0))))
85       return;
86     if (Sec.Type == wasm::WASM_SEC_USER) {
87       if ((Err = parseUserSection(Sec, Sec.Content.data(), Sec.Content.size())))
88         return;
89     }
90     Sections.push_back(Sec);
91   }
92 }
93
94 Error WasmObjectFile::parseUserSection(wasm::WasmSection &Sec,
95                                        const uint8_t *Ptr, size_t Length) {
96   Sec.Name = readString(Ptr);
97   return Error::success();
98 }
99
100 const uint8_t *WasmObjectFile::getPtr(size_t Offset) const {
101   return reinterpret_cast<const uint8_t *>(getData().substr(Offset, 1).data());
102 }
103
104 const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
105   return Header;
106 }
107
108 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
109   llvm_unreachable("not yet implemented");
110 }
111
112 std::error_code WasmObjectFile::printSymbolName(raw_ostream &OS,
113                                                 DataRefImpl Symb) const {
114   llvm_unreachable("not yet implemented");
115   return object_error::invalid_symbol_index;
116 }
117
118 uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
119   llvm_unreachable("not yet implemented");
120   return 0;
121 }
122
123 basic_symbol_iterator WasmObjectFile::symbol_begin() const {
124   return BasicSymbolRef(DataRefImpl(), this);
125 }
126
127 basic_symbol_iterator WasmObjectFile::symbol_end() const {
128   return BasicSymbolRef(DataRefImpl(), this);
129 }
130
131 Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
132   llvm_unreachable("not yet implemented");
133   return errorCodeToError(object_error::invalid_symbol_index);
134 }
135
136 Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
137   llvm_unreachable("not yet implemented");
138   return errorCodeToError(object_error::invalid_symbol_index);
139 }
140
141 uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
142   llvm_unreachable("not yet implemented");
143   return 0;
144 }
145
146 uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
147   llvm_unreachable("not yet implemented");
148   return 0;
149 }
150
151 uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
152   llvm_unreachable("not yet implemented");
153   return 0;
154 }
155
156 Expected<SymbolRef::Type>
157 WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
158   llvm_unreachable("not yet implemented");
159   return errorCodeToError(object_error::invalid_symbol_index);
160 }
161
162 Expected<section_iterator>
163 WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
164   llvm_unreachable("not yet implemented");
165   return errorCodeToError(object_error::invalid_symbol_index);
166 }
167
168 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
169
170 std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
171                                                StringRef &Res) const {
172   const wasm::WasmSection &S = Sections[Sec.d.a];
173 #define ECase(X)                                                               \
174   case wasm::WASM_SEC_##X:                                                     \
175     Res = #X;                                                                  \
176     break
177   switch (S.Type) {
178     ECase(TYPE);
179     ECase(IMPORT);
180     ECase(FUNCTION);
181     ECase(TABLE);
182     ECase(MEMORY);
183     ECase(GLOBAL);
184     ECase(EXPORT);
185     ECase(START);
186     ECase(ELEM);
187     ECase(CODE);
188     ECase(DATA);
189   case wasm::WASM_SEC_USER:
190     Res = S.Name;
191     break;
192   default:
193     return object_error::invalid_section_index;
194   }
195 #undef ECase
196   return std::error_code();
197 }
198
199 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
200
201 uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
202   const wasm::WasmSection &S = Sections[Sec.d.a];
203   return S.Content.size();
204 }
205
206 std::error_code WasmObjectFile::getSectionContents(DataRefImpl Sec,
207                                                    StringRef &Res) const {
208   const wasm::WasmSection &S = Sections[Sec.d.a];
209   // This will never fail since wasm sections can never be empty (user-sections
210   // must have a name and non-user sections each have a defined structure).
211   Res = StringRef(reinterpret_cast<const char *>(S.Content.data()),
212                   S.Content.size());
213   return std::error_code();
214 }
215
216 uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const {
217   return 1;
218 }
219
220 bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const {
221   return false;
222 }
223
224 bool WasmObjectFile::isSectionText(DataRefImpl Sec) const {
225   const wasm::WasmSection &S = Sections[Sec.d.a];
226   return S.Type == wasm::WASM_SEC_CODE;
227 }
228
229 bool WasmObjectFile::isSectionData(DataRefImpl Sec) const {
230   const wasm::WasmSection &S = Sections[Sec.d.a];
231   return S.Type == wasm::WASM_SEC_DATA;
232 }
233
234 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
235
236 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
237
238 bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }
239
240 relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Sec) const {
241   llvm_unreachable("not yet implemented");
242   RelocationRef Rel;
243   return relocation_iterator(Rel);
244 }
245
246 relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Sec) const {
247   llvm_unreachable("not yet implemented");
248   RelocationRef Rel;
249   return relocation_iterator(Rel);
250 }
251
252 section_iterator WasmObjectFile::getRelocatedSection(DataRefImpl Sec) const {
253   llvm_unreachable("not yet implemented");
254   SectionRef Ref;
255   return section_iterator(Ref);
256 }
257
258 void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
259   llvm_unreachable("not yet implemented");
260 }
261
262 uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Rel) const {
263   llvm_unreachable("not yet implemented");
264   return 0;
265 }
266
267 symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
268   llvm_unreachable("not yet implemented");
269   SymbolRef Ref;
270   return symbol_iterator(Ref);
271 }
272
273 uint64_t WasmObjectFile::getRelocationType(DataRefImpl Rel) const {
274   llvm_unreachable("not yet implemented");
275   return 0;
276 }
277
278 void WasmObjectFile::getRelocationTypeName(
279     DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
280   llvm_unreachable("not yet implemented");
281 }
282
283 section_iterator WasmObjectFile::section_begin() const {
284   DataRefImpl Ref;
285   Ref.d.a = 0;
286   return section_iterator(SectionRef(Ref, this));
287 }
288
289 section_iterator WasmObjectFile::section_end() const {
290   DataRefImpl Ref;
291   Ref.d.a = Sections.size();
292   return section_iterator(SectionRef(Ref, this));
293 }
294
295 uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }
296
297 StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
298
299 unsigned WasmObjectFile::getArch() const { return Triple::wasm32; }
300
301 SubtargetFeatures WasmObjectFile::getFeatures() const {
302   return SubtargetFeatures();
303 }
304
305 bool WasmObjectFile::isRelocatableObject() const { return false; }
306
307 const wasm::WasmSection *
308 WasmObjectFile::getWasmSection(const SectionRef &Section) const {
309   return &Sections[Section.getRawDataRefImpl().d.a];
310 }
311
312 } // end namespace object
313 } // end namespace llvm