WasmWriter.cpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "WasmWriter.h"
  9. #include "llvm/BinaryFormat/Wasm.h"
  10. #include "llvm/Support/Endian.h"
  11. #include "llvm/Support/Errc.h"
  12. #include "llvm/Support/LEB128.h"
  13. #include "llvm/Support/raw_ostream.h"
  14. namespace llvm {
  15. namespace objcopy {
  16. namespace wasm {
  17. using namespace object;
  18. using namespace llvm::wasm;
  19. Writer::SectionHeader Writer::createSectionHeader(const Section &S,
  20. size_t &SectionSize) {
  21. SectionHeader Header;
  22. raw_svector_ostream OS(Header);
  23. OS << S.SectionType;
  24. bool HasName = S.SectionType == WASM_SEC_CUSTOM;
  25. SectionSize = S.Contents.size();
  26. if (HasName)
  27. SectionSize += getULEB128Size(S.Name.size()) + S.Name.size();
  28. // Pad the LEB value out to 5 bytes to make it a predictable size, and
  29. // match the behavior of clang.
  30. encodeULEB128(SectionSize, OS, 5);
  31. if (HasName) {
  32. encodeULEB128(S.Name.size(), OS);
  33. OS << S.Name;
  34. }
  35. // Total section size is the content size plus 1 for the section type and
  36. // 5 for the LEB-encoded size.
  37. SectionSize = SectionSize + 1 + 5;
  38. return Header;
  39. }
  40. size_t Writer::finalize() {
  41. size_t ObjectSize = sizeof(WasmMagic) + sizeof(WasmVersion);
  42. SectionHeaders.reserve(Obj.Sections.size());
  43. // Finalize the headers of each section so we know the total size.
  44. for (const Section &S : Obj.Sections) {
  45. size_t SectionSize;
  46. SectionHeaders.push_back(createSectionHeader(S, SectionSize));
  47. ObjectSize += SectionSize;
  48. }
  49. return ObjectSize;
  50. }
  51. Error Writer::write() {
  52. size_t TotalSize = finalize();
  53. Out.reserveExtraSpace(TotalSize);
  54. // Write the header.
  55. Out.write(Obj.Header.Magic.data(), Obj.Header.Magic.size());
  56. uint32_t Version;
  57. support::endian::write32le(&Version, Obj.Header.Version);
  58. Out.write(reinterpret_cast<const char *>(&Version), sizeof(Version));
  59. // Write each section.
  60. for (size_t I = 0, S = SectionHeaders.size(); I < S; ++I) {
  61. Out.write(SectionHeaders[I].data(), SectionHeaders[I].size());
  62. Out.write(reinterpret_cast<const char *>(Obj.Sections[I].Contents.data()),
  63. Obj.Sections[I].Contents.size());
  64. }
  65. return Error::success();
  66. }
  67. } // end namespace wasm
  68. } // end namespace objcopy
  69. } // end namespace llvm