1 //===- Writer.cpp ---------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "llvm/BinaryFormat/Wasm.h"
11 #include "llvm/Support/Endian.h"
12 #include "llvm/Support/Errc.h"
13 #include "llvm/Support/LEB128.h"
14 #include "llvm/Support/raw_ostream.h"
20 using namespace object
;
21 using namespace llvm::wasm
;
23 Writer::SectionHeader
Writer::createSectionHeader(const Section
&S
,
24 size_t &SectionSize
) {
26 raw_svector_ostream
OS(Header
);
28 bool HasName
= S
.SectionType
== WASM_SEC_CUSTOM
;
29 SectionSize
= S
.Contents
.size();
31 SectionSize
+= getULEB128Size(S
.Name
.size()) + S
.Name
.size();
32 // Pad the LEB value out to 5 bytes to make it a predictable size, and
33 // match the behavior of clang.
34 encodeULEB128(SectionSize
, OS
, 5);
36 encodeULEB128(S
.Name
.size(), OS
);
39 // Total section size is the content size plus 1 for the section type and
40 // 5 for the LEB-encoded size.
41 SectionSize
= SectionSize
+ 1 + 5;
45 size_t Writer::finalize() {
46 size_t ObjectSize
= sizeof(WasmMagic
) + sizeof(WasmVersion
);
47 SectionHeaders
.reserve(Obj
.Sections
.size());
48 // Finalize the headers of each section so we know the total size.
49 for (const Section
&S
: Obj
.Sections
) {
51 SectionHeaders
.push_back(createSectionHeader(S
, SectionSize
));
52 ObjectSize
+= SectionSize
;
57 Error
Writer::write() {
58 size_t TotalSize
= finalize();
59 Out
.reserveExtraSpace(TotalSize
);
62 Out
.write(Obj
.Header
.Magic
.data(), Obj
.Header
.Magic
.size());
64 support::endian::write32le(&Version
, Obj
.Header
.Version
);
65 Out
.write(reinterpret_cast<const char *>(&Version
), sizeof(Version
));
67 // Write each section.
68 for (size_t I
= 0, S
= SectionHeaders
.size(); I
< S
; ++I
) {
69 Out
.write(SectionHeaders
[I
].data(), SectionHeaders
[I
].size());
70 Out
.write(reinterpret_cast<const char *>(Obj
.Sections
[I
].Contents
.data()),
71 Obj
.Sections
[I
].Contents
.size());
74 return Error::success();
77 } // end namespace wasm
78 } // end namespace objcopy
79 } // end namespace llvm