[llvm-objdump] - Import the test/Object/X86/no-start-symbol.test test case and rewrit...
[llvm-complete.git] / lib / Support / BinaryStreamWriter.cpp
blob986e18da281dbfee7d899afad334d15b725551a0
1 //===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/BinaryStreamWriter.h"
11 #include "llvm/Support/BinaryStreamError.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamRef.h"
14 #include "llvm/Support/LEB128.h"
16 using namespace llvm;
18 BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef Ref)
19 : Stream(Ref) {}
21 BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStream &Stream)
22 : Stream(Stream) {}
24 BinaryStreamWriter::BinaryStreamWriter(MutableArrayRef<uint8_t> Data,
25 llvm::support::endianness Endian)
26 : Stream(Data, Endian) {}
28 Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) {
29 if (auto EC = Stream.writeBytes(Offset, Buffer))
30 return EC;
31 Offset += Buffer.size();
32 return Error::success();
35 Error BinaryStreamWriter::writeULEB128(uint64_t Value) {
36 uint8_t EncodedBytes[10] = {0};
37 unsigned Size = encodeULEB128(Value, &EncodedBytes[0]);
38 return writeBytes({EncodedBytes, Size});
41 Error BinaryStreamWriter::writeSLEB128(int64_t Value) {
42 uint8_t EncodedBytes[10] = {0};
43 unsigned Size = encodeSLEB128(Value, &EncodedBytes[0]);
44 return writeBytes({EncodedBytes, Size});
47 Error BinaryStreamWriter::writeCString(StringRef Str) {
48 if (auto EC = writeFixedString(Str))
49 return EC;
50 if (auto EC = writeObject('\0'))
51 return EC;
53 return Error::success();
56 Error BinaryStreamWriter::writeFixedString(StringRef Str) {
58 return writeBytes(arrayRefFromStringRef(Str));
61 Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) {
62 return writeStreamRef(Ref, Ref.getLength());
65 Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) {
66 BinaryStreamReader SrcReader(Ref.slice(0, Length));
67 // This is a bit tricky. If we just call readBytes, we are requiring that it
68 // return us the entire stream as a contiguous buffer. There is no guarantee
69 // this can be satisfied by returning a reference straight from the buffer, as
70 // an implementation may not store all data in a single contiguous buffer. So
71 // we iterate over each contiguous chunk, writing each one in succession.
72 while (SrcReader.bytesRemaining() > 0) {
73 ArrayRef<uint8_t> Chunk;
74 if (auto EC = SrcReader.readLongestContiguousChunk(Chunk))
75 return EC;
76 if (auto EC = writeBytes(Chunk))
77 return EC;
79 return Error::success();
82 std::pair<BinaryStreamWriter, BinaryStreamWriter>
83 BinaryStreamWriter::split(uint32_t Off) const {
84 assert(getLength() >= Off);
86 WritableBinaryStreamRef First = Stream.drop_front(Offset);
88 WritableBinaryStreamRef Second = First.drop_front(Off);
89 First = First.keep_front(Off);
90 BinaryStreamWriter W1{First};
91 BinaryStreamWriter W2{Second};
92 return std::make_pair(W1, W2);
95 Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
96 uint32_t NewOffset = alignTo(Offset, Align);
97 if (NewOffset > getLength())
98 return make_error<BinaryStreamError>(stream_error_code::stream_too_short);
99 while (Offset < NewOffset)
100 if (auto EC = writeInteger('\0'))
101 return EC;
102 return Error::success();