You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.3 KiB
96 lines
3.3 KiB
// Copyright 2023 The Centipede Authors.
|
|
//
|
|
// 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
|
|
//
|
|
// https://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_CENTIPEDE_PC_INFO_H_
|
|
#define THIRD_PARTY_CENTIPEDE_PC_INFO_H_
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <istream>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace fuzztest::internal {
|
|
|
|
// PCInfo is a pair {PC, bit mask with PC flags}.
|
|
// PCInfo objects are generated by the compiler and can be extracted from the
|
|
// binary, see https://clang.llvm.org/docs/SanitizerCoverage.html#pc-table.
|
|
// PCInfo objects can also be created by analyzing the binary with objdump.
|
|
struct PCInfo {
|
|
enum PCFlags : uintptr_t {
|
|
kFuncEntry = 1 << 0, // The PC is the function entry block.
|
|
};
|
|
|
|
uintptr_t pc{};
|
|
uintptr_t flags{};
|
|
|
|
bool has_flag(PCFlags f) const { return flags & f; }
|
|
|
|
bool operator==(const PCInfo &rhs) const;
|
|
};
|
|
|
|
// Array of PCInfo-s.
|
|
// PCTable is created by the compiler/linker in the instrumented binary.
|
|
// The order of elements is significant: each element corresponds
|
|
// to the coverage counter with the same index.
|
|
// Every PCInfo that is kFuncEntry is followed by PCInfo-s from the same
|
|
// function.
|
|
using PCTable = std::vector<PCInfo>;
|
|
|
|
// Reads a PCTable from `in`, returns it. Returns empty table on error.
|
|
PCTable ReadPcTable(std::istream &in);
|
|
|
|
// Writes the contents of `pc_table` in the format expected by `ReadPCTable`.
|
|
void WritePcTable(const PCTable &pc_table, std::ostream &out);
|
|
|
|
// PCGuard is used during run-time as a compressed reference to PCInfo.
|
|
// The SanitizerCoverage's 'Tracing PCs with guards'
|
|
// (https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards)
|
|
// passes a pointer to a 32-bit object, unique for every instrumented PC.
|
|
// At the DSO initialization time, we initialize these unique 32-bit objects
|
|
// to represent the information about the PCs.
|
|
struct PCGuard {
|
|
// True if this is a function's entry PC.
|
|
// This information may not be available, and so the code should tolerate
|
|
// the situation where no PC is marked as a function entry.
|
|
uint32_t is_function_entry : 1;
|
|
// The index of the PC.
|
|
uint32_t pc_index : 31;
|
|
|
|
// pc_index is 31-bit, so we can't have more than this number of PCs.
|
|
static constexpr size_t kMaxNumPCs = 1ULL << 31;
|
|
|
|
// Invalid value of pc_index.
|
|
static constexpr uint32_t kInvalidPcIndex = kMaxNumPCs - 1;
|
|
|
|
// Returns true if `*this` is valid.
|
|
bool IsValid() const { return pc_index != kInvalidPcIndex; }
|
|
};
|
|
|
|
// DsoInfo represents a single SanCov-instrumented DSO (library or main binary).
|
|
struct DsoInfo {
|
|
// Path to the file on disk, which can be used for symbolization.
|
|
std::string path;
|
|
|
|
// Number of SanCov-instrumented PCs in this DSO.
|
|
size_t num_instrumented_pcs = 0;
|
|
};
|
|
|
|
// Array of DsoInfo.
|
|
using DsoTable = std::vector<DsoInfo>;
|
|
|
|
} // namespace fuzztest::internal
|
|
|
|
#endif // THIRD_PARTY_CENTIPEDE_PC_INFO_H_
|
|
|