1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
/*
Copyright (C) 2006 - 2015 Evan Teran
evan.teran@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef REGISTER_H_20100329_
#define REGISTER_H_20100329_
#include "API.h"
#include "Types.h"
#include "Util.h"
#include <QCoreApplication>
#include <QString>
#include <cassert>
#include <cstring>
#include <type_traits>
class EDB_EXPORT Register {
Q_DECLARE_TR_FUNCTIONS(Register)
public:
enum Type {
// groups, these catagories should remain as portable as possible
TYPE_INVALID = 0x0000,
TYPE_GPR = 0x0001,
TYPE_IP = 0x0002,
TYPE_SEG = 0x0004,
TYPE_COND = 0x0008,
TYPE_FPU = 0x0010,
TYPE_SIMD = 0x0020,
};
// Expand when AVX-512 instructions and state are supported
using StoredType = edb::value256;
public:
Register();
Register(const Register &other) = default;
Register &operator=(const Register &rhs) = default;
public:
bool operator==(const Register &rhs) const;
bool operator!=(const Register &rhs) const;
public:
bool valid() const { return type_ != TYPE_INVALID; }
explicit operator bool() const { return valid(); }
Type type() const { return type_; }
QString name() const { return name_; }
std::size_t bitSize() const { return bitSize_; }
const char *rawData() const { return reinterpret_cast<const char *>(&value_); }
template <class T>
T value() const { return T(value_); }
// Return the value, zero-extended to address_t to be usable in address calculations
edb::address_t valueAsAddress() const;
uint64_t valueAsInteger() const {
return valueAsAddress().toUint();
}
int64_t valueAsSignedInteger() const {
uint64_t result = valueAsInteger();
// If MSB is set, sign extend the result
if (result & (1ll << (bitSize_ - 1))) {
result = -1ll;
std::memcpy(&result, &value_, bitSize_ / 8);
}
return result;
}
void setScalarValue(std::uint64_t newValue);
template <typename T>
void setValueFrom(const T &source) {
assert(bitSize_ <= 8 * sizeof(source));
// NOTE(eteran): used to avoid warnings from GCC >= 8.2
auto from = reinterpret_cast<const char *>(&source);
auto to = reinterpret_cast<char *>(&value_);
std::memcpy(to, from, bitSize_ / 8);
}
QString toHexString() const;
private:
QString name_ = tr("<unknown>");
StoredType value_ = {};
Type type_ = TYPE_INVALID;
std::size_t bitSize_ = 0;
template <std::size_t bitSize, typename T>
friend Register make_Register(const QString &name, T value, Register::Type type);
};
template <std::size_t BitSize, typename T>
Register make_Register(const QString &name, T value, Register::Type type) {
constexpr std::size_t bitSize = (BitSize ? BitSize : 8 * sizeof(T));
static_assert(BitSize % 8 == 0, "Strange bit size");
Register reg;
reg.name_ = name;
reg.type_ = type;
reg.bitSize_ = bitSize;
constexpr std::size_t size = bitSize / 8;
static_assert(size <= sizeof(T), "ValueType appears smaller than size specified");
util::mark_memory(®.value_, sizeof(reg.value_));
// NOTE(eteran): used to avoid warnings from GCC >= 8.2
auto from = reinterpret_cast<const char *>(&value);
auto to = reinterpret_cast<char *>(®.value_);
std::memcpy(to, from, size);
return reg;
}
template <typename T>
Register make_Register(const QString &name, T value, Register::Type type) {
return make_Register<0>(name, value, type);
}
#endif
|