blob: a2438d3da0bb4b2e7e0c87aad46101b8471cecaa [file]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the ContiguousBlobAccumulator methods declared in
/// ContiguousBlobAccumulator.h.
///
//===----------------------------------------------------------------------===//
#include "llvm/ObjectYAML/ContiguousBlobAccumulator.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/LEB128.h"
using namespace llvm;
using namespace llvm::yaml;
bool ContiguousBlobAccumulator::checkLimit(uint64_t Size) {
uint64_t Off = getOffset();
if (!ReachedLimitErr && Off <= MaxSize && Size <= MaxSize - Off)
return true;
if (!ReachedLimitErr)
ReachedLimitErr = createStringError(errc::invalid_argument,
"reached the output size limit");
return false;
}
uint64_t ContiguousBlobAccumulator::padToAlignment(unsigned Align) {
uint64_t CurrentOffset = getOffset();
if (ReachedLimitErr)
return CurrentOffset;
uint64_t AlignedOffset = alignTo(CurrentOffset, Align == 0 ? 1 : Align);
uint64_t PaddingSize = AlignedOffset - CurrentOffset;
if (!checkLimit(PaddingSize))
return CurrentOffset;
writeZeros(PaddingSize);
return AlignedOffset;
}
void ContiguousBlobAccumulator::writeAsBinary(const BinaryRef &Bin,
uint64_t N) {
// Only min(binary_size(), N) bytes are written.
if (!checkLimit(std::min<uint64_t>(Bin.binary_size(), N)))
return;
Bin.writeAsBinary(OS, N);
}
unsigned ContiguousBlobAccumulator::writeULEB128(uint64_t Val) {
if (!checkLimit(sizeof(uint64_t)))
return 0;
return encodeULEB128(Val, OS);
}
unsigned ContiguousBlobAccumulator::writeSLEB128(int64_t Val) {
if (!checkLimit(10))
return 0;
return encodeSLEB128(Val, OS);
}
void ContiguousBlobAccumulator::updateDataAt(uint64_t Pos, const void *Data,
size_t Size) {
assert(Pos >= InitialOffset && Pos + Size <= getOffset());
memcpy(&Buf[Pos - InitialOffset], Data, Size);
}