brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · 2f18740 Raw
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