1//===----------------------------------------------------------------------===//
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///
9/// \file
10/// This file implements the ContiguousBlobAccumulator methods declared in
11/// ContiguousBlobAccumulator.h.
12///
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ObjectYAML/ContiguousBlobAccumulator.h"
16#include "llvm/ObjectYAML/YAML.h"
17#include "llvm/Support/Errc.h"
18#include "llvm/Support/LEB128.h"
19
20using namespace llvm;
21using namespace llvm::yaml;
22
23bool ContiguousBlobAccumulator::checkLimit(uint64_t Size) {
24 uint64_t Off = getOffset();
25 if (!ReachedLimitErr && Off <= MaxSize && Size <= MaxSize - Off)
26 return true;
27 if (!ReachedLimitErr)
28 ReachedLimitErr = createStringError(EC: errc::invalid_argument,
29 S: "reached the output size limit");
30 return false;
31}
32
33uint64_t ContiguousBlobAccumulator::padToAlignment(unsigned Align) {
34 uint64_t CurrentOffset = getOffset();
35 if (ReachedLimitErr)
36 return CurrentOffset;
37
38 uint64_t AlignedOffset = alignTo(Value: CurrentOffset, Align: Align == 0 ? 1 : Align);
39 uint64_t PaddingSize = AlignedOffset - CurrentOffset;
40 if (!checkLimit(Size: PaddingSize))
41 return CurrentOffset;
42
43 writeZeros(Num: PaddingSize);
44 return AlignedOffset;
45}
46
47void ContiguousBlobAccumulator::writeAsBinary(const BinaryRef &Bin,
48 uint64_t N) {
49 // Only min(binary_size(), N) bytes are written.
50 if (!checkLimit(Size: std::min<uint64_t>(a: Bin.binary_size(), b: N)))
51 return;
52 Bin.writeAsBinary(OS, N);
53}
54
55unsigned ContiguousBlobAccumulator::writeULEB128(uint64_t Val) {
56 if (!checkLimit(Size: sizeof(uint64_t)))
57 return 0;
58 return encodeULEB128(Value: Val, OS);
59}
60
61unsigned ContiguousBlobAccumulator::writeSLEB128(int64_t Val) {
62 if (!checkLimit(Size: 10))
63 return 0;
64 return encodeSLEB128(Value: Val, OS);
65}
66
67void ContiguousBlobAccumulator::updateDataAt(uint64_t Pos, const void *Data,
68 size_t Size) {
69 assert(Pos >= InitialOffset && Pos + Size <= getOffset());
70 memcpy(dest: &Buf[Pos - InitialOffset], src: Data, n: Size);
71}
72