81 lines · cpp
1//===- WasmWriter.cpp -----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "WasmWriter.h"10#include "llvm/BinaryFormat/Wasm.h"11#include "llvm/Support/Endian.h"12#include "llvm/Support/LEB128.h"13#include "llvm/Support/raw_ostream.h"14 15namespace llvm {16namespace objcopy {17namespace wasm {18 19using namespace object;20using namespace llvm::wasm;21 22Writer::SectionHeader Writer::createSectionHeader(const Section &S,23 size_t &SectionSize) {24 SectionHeader Header;25 raw_svector_ostream OS(Header);26 OS << S.SectionType;27 bool HasName = S.SectionType == WASM_SEC_CUSTOM;28 SectionSize = S.Contents.size();29 if (HasName)30 SectionSize += getULEB128Size(S.Name.size()) + S.Name.size();31 // If we read this section from an object file, use its original size for the32 // padding of the LEB value to avoid changing the file size. Otherwise, pad33 // out to 5 bytes to make it predictable, and match the behavior of clang.34 unsigned HeaderSecSizeEncodingLen = S.HeaderSecSizeEncodingLen.value_or(5);35 encodeULEB128(SectionSize, OS, HeaderSecSizeEncodingLen);36 if (HasName) {37 encodeULEB128(S.Name.size(), OS);38 OS << S.Name;39 }40 // Total section size is the content size plus 1 for the section type and41 // the LEB-encoded size.42 SectionSize = SectionSize + 1 + HeaderSecSizeEncodingLen;43 return Header;44}45 46size_t Writer::finalize() {47 size_t ObjectSize = sizeof(WasmMagic) + sizeof(WasmVersion);48 SectionHeaders.reserve(Obj.Sections.size());49 // Finalize the headers of each section so we know the total size.50 for (const Section &S : Obj.Sections) {51 size_t SectionSize;52 SectionHeaders.push_back(createSectionHeader(S, SectionSize));53 ObjectSize += SectionSize;54 }55 return ObjectSize;56}57 58Error Writer::write() {59 size_t TotalSize = finalize();60 Out.reserveExtraSpace(TotalSize);61 62 // Write the header.63 Out.write(Obj.Header.Magic.data(), Obj.Header.Magic.size());64 uint32_t Version;65 support::endian::write32le(&Version, Obj.Header.Version);66 Out.write(reinterpret_cast<const char *>(&Version), sizeof(Version));67 68 // Write each section.69 for (size_t I = 0, S = SectionHeaders.size(); I < S; ++I) {70 Out.write(SectionHeaders[I].data(), SectionHeaders[I].size());71 Out.write(reinterpret_cast<const char *>(Obj.Sections[I].Contents.data()),72 Obj.Sections[I].Contents.size());73 }74 75 return Error::success();76}77 78} // end namespace wasm79} // end namespace objcopy80} // end namespace llvm81