Changes include: * CPU check has been broken up into a number of small libraries * BoringSSL option has been removed * Better abseil integration
125 lines
3.8 KiB
C++
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_
|