1 //===- WasmObjectFile.cpp - Wasm object file implementation -----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Object/Wasm.h"
11 #include "llvm/Support/Endian.h"
12 #include "llvm/Support/LEB128.h"
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);
22 return std::move(Err);
24 return std::move(ObjectFile);
29 uint32_t readUint32(const uint8_t *&Ptr) {
30 uint32_t Result = support::endian::read32le(Ptr);
31 Ptr += sizeof(Result);
35 uint64_t readULEB128(const uint8_t *&Ptr) {
37 uint64_t Result = decodeULEB128(Ptr, &Count);
42 StringRef readString(const uint8_t *&Ptr) {
43 uint32_t StringLen = readULEB128(Ptr);
44 StringRef Return = StringRef(reinterpret_cast<const char *>(Ptr), StringLen);
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);
56 return make_error<StringError>("Zero length section",
57 object_error::parse_failed);
58 Section.Content = ArrayRef<uint8_t>(Ptr, Size);
60 return Error::success();
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);
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);
81 const uint8_t *Eof = getPtr(getData().size());
82 wasm::WasmSection Sec;
84 if ((Err = readSection(Sec, Ptr, getPtr(0))))
86 if (Sec.Type == wasm::WASM_SEC_USER) {
87 if ((Err = parseUserSection(Sec, Sec.Content.data(), Sec.Content.size())))
90 Sections.push_back(Sec);
94 Error WasmObjectFile::parseUserSection(wasm::WasmSection &Sec,
95 const uint8_t *Ptr, size_t Length) {
96 Sec.Name = readString(Ptr);
97 return Error::success();
100 const uint8_t *WasmObjectFile::getPtr(size_t Offset) const {
101 return reinterpret_cast<const uint8_t *>(getData().substr(Offset, 1).data());
104 const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
108 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
109 llvm_unreachable("not yet implemented");
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;
118 uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
119 llvm_unreachable("not yet implemented");
123 basic_symbol_iterator WasmObjectFile::symbol_begin() const {
124 return BasicSymbolRef(DataRefImpl(), this);
127 basic_symbol_iterator WasmObjectFile::symbol_end() const {
128 return BasicSymbolRef(DataRefImpl(), this);
131 Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
132 llvm_unreachable("not yet implemented");
133 return errorCodeToError(object_error::invalid_symbol_index);
136 Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
137 llvm_unreachable("not yet implemented");
138 return errorCodeToError(object_error::invalid_symbol_index);
141 uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
142 llvm_unreachable("not yet implemented");
146 uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
147 llvm_unreachable("not yet implemented");
151 uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
152 llvm_unreachable("not yet implemented");
156 Expected<SymbolRef::Type>
157 WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
158 llvm_unreachable("not yet implemented");
159 return errorCodeToError(object_error::invalid_symbol_index);
162 Expected<section_iterator>
163 WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
164 llvm_unreachable("not yet implemented");
165 return errorCodeToError(object_error::invalid_symbol_index);
168 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
170 std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
171 StringRef &Res) const {
172 const wasm::WasmSection &S = Sections[Sec.d.a];
174 case wasm::WASM_SEC_##X: \
189 case wasm::WASM_SEC_USER:
193 return object_error::invalid_section_index;
196 return std::error_code();
199 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
201 uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
202 const wasm::WasmSection &S = Sections[Sec.d.a];
203 return S.Content.size();
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()),
213 return std::error_code();
216 uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const {
220 bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const {
224 bool WasmObjectFile::isSectionText(DataRefImpl Sec) const {
225 const wasm::WasmSection &S = Sections[Sec.d.a];
226 return S.Type == wasm::WASM_SEC_CODE;
229 bool WasmObjectFile::isSectionData(DataRefImpl Sec) const {
230 const wasm::WasmSection &S = Sections[Sec.d.a];
231 return S.Type == wasm::WASM_SEC_DATA;
234 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
236 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
238 bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }
240 relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Sec) const {
241 llvm_unreachable("not yet implemented");
243 return relocation_iterator(Rel);
246 relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Sec) const {
247 llvm_unreachable("not yet implemented");
249 return relocation_iterator(Rel);
252 section_iterator WasmObjectFile::getRelocatedSection(DataRefImpl Sec) const {
253 llvm_unreachable("not yet implemented");
255 return section_iterator(Ref);
258 void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
259 llvm_unreachable("not yet implemented");
262 uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Rel) const {
263 llvm_unreachable("not yet implemented");
267 symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
268 llvm_unreachable("not yet implemented");
270 return symbol_iterator(Ref);
273 uint64_t WasmObjectFile::getRelocationType(DataRefImpl Rel) const {
274 llvm_unreachable("not yet implemented");
278 void WasmObjectFile::getRelocationTypeName(
279 DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
280 llvm_unreachable("not yet implemented");
283 section_iterator WasmObjectFile::section_begin() const {
286 return section_iterator(SectionRef(Ref, this));
289 section_iterator WasmObjectFile::section_end() const {
291 Ref.d.a = Sections.size();
292 return section_iterator(SectionRef(Ref, this));
295 uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }
297 StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
299 unsigned WasmObjectFile::getArch() const { return Triple::wasm32; }
301 SubtargetFeatures WasmObjectFile::getFeatures() const {
302 return SubtargetFeatures();
305 bool WasmObjectFile::isRelocatableObject() const { return false; }
307 const wasm::WasmSection *
308 WasmObjectFile::getWasmSection(const SectionRef &Section) const {
309 return &Sections[Section.getRawDataRefImpl().d.a];
312 } // end namespace object
313 } // end namespace llvm