| //===----------------------------------------------------------------------===// | |
| // | |
| // 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) { | |
| uint64_t CurrentOffset = getOffset(); | |
| bool IsValidRange = Pos >= InitialOffset && Pos <= CurrentOffset && | |
| Size <= CurrentOffset - Pos; | |
| if (!IsValidRange) { | |
| assert(ReachedLimitErr && | |
| "update range is invalid without reaching the output size limit"); | |
| return; | |
| } | |
| memcpy(&Buf[Pos - InitialOffset], Data, Size); | |
| } |