Files
cpu-check/malign_buffer.h
Kevin Boyd 83eed0a886 Sync with upstream repo.
Changes include:
* CPU check has been broken up into a number of small libraries
* BoringSSL option has been removed
* Better abseil integration
2020-11-09 13:03:39 -08:00

125 lines
3.8 KiB
C++

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_CPU_CHECK_MALIGN_BUFFER_H_
#define THIRD_PARTY_CPU_CHECK_MALIGN_BUFFER_H_
#include <random>
#include <string>
#include "absl/strings/string_view.h"
namespace cpu_check {
// Data buffer supporting various alignments, copy mechanisms, and verification
// methods.
class MalignBuffer {
public:
struct PunchedHole {
std::string ToString() const;
size_t start = 0;
size_t length = 0;
unsigned char v = 0x53;
};
enum CopyMethod {
kMemcpy,
kRepMov,
kSseBy128,
kAvxBy256,
kAvxBy512,
};
// Returns name of given CopyMethod.
static std::string ToString(CopyMethod m);
static const size_t kPageSize;
static const size_t kCacheLineSize;
// Returns a random alignment offset in range [0..kPageSize-1].
static size_t RandomAlignment(uint64_t seed);
// Helper to make MSAN happy. NOP if memory sanitizer is not enabled.
static void InitializeMemoryForSanitizer(char* addr, size_t size);
// Constructs MalignBuffer of specified capacity.
MalignBuffer(size_t capacity);
// Constructs and initializes MalignBuffer with specified alignment and
// content. Useful for unit tests.
// REQUIRES:
// alignment_offset < kPageSize
MalignBuffer(size_t alignment_offset, absl::string_view s);
~MalignBuffer();
// Initializes buffer to specified alignment.
// REQUIRES:
// alignment_offset < kPageSize
// length <= this.capacity_.
void Initialize(size_t alignment_offset, size_t length);
const char* data() const { return buffer_address_; }
char* data() { return buffer_address_; }
size_t size() const { return length_; }
// REQUIRES length <= capacity_.
void resize(size_t length);
// Compares 'this' to 'that' returning empty string if identical.
// If not identical, returns a syndrome, currently Hamming distance,
// corrupted subrange bounds, and the diffs.
std::string Syndrome(const MalignBuffer& that) const;
// Validated data copy from source to 'this'.
// 'this' must be appropriately sized.
// Returns syndrome upon copy failure.
std::string CopyFrom(const MalignBuffer& that, CopyMethod m);
// Unvalidated copy to 'this'.
void CopyFrom(absl::string_view src, CopyMethod m);
void CopyFrom(size_t pos, absl::string_view src, CopyMethod m);
// Randomly flushes cache lines.
void RandomFlush(std::knuth_b* rng) const;
// Conventional or rep;sto memset operation, according to 'use_rep_stos'.
void Memset(size_t offset, unsigned char v, size_t length, bool use_rep_stos);
// Memsets buffer to 'hole.v', using rep;stos operation if
// 'use_rep_stos' set;
void PunchHole(const PunchedHole& hole, bool use_rep_stos);
// Hints to the OS to release the buffer's memory.
void MadviseDontNeed() const;
// Returns random PunchedHole within 'this'.
MalignBuffer::PunchedHole RandomPunchedHole(uint64_t seed) const;
private:
static size_t RoundUpToPageSize(size_t k);
std::string CorruptionSyndrome(const MalignBuffer& that) const;
std::string CrackId(uint64_t) const;
const size_t capacity_;
void* base_address_ = nullptr;
size_t alignment_offset_ = 0;
size_t length_ = 0; // Usable length
char* buffer_address_ = nullptr;
};
} // namespace cpu_check
#endif // THIRD_PARTY_CPU_CHECK_MALIGN_BUFFER_H_