Compare commits

..

3 Commits

Author SHA1 Message Date
Lioncash
c7387e6504 string_util: Remove ArrayToString()
An old function from Dolphin. This is also unused, and pretty inflexible
when it comes to printing out different data types (for example, one
might not want to print out an array of u8s but a different type
instead. Given we use fmt, there's no need to keep this implementation
of the function around.
2018-11-13 18:14:11 -05:00
Lioncash
f1219e3a87 string_util: Remove TryParse()
This is an unused hold-over from Dolphin that was primarily used to
parse values out of the .ini files. Given we already have libraries that
do this for us, we don't need to keep this around.
2018-11-13 18:13:45 -05:00
Lioncash
9bc18eada8 string_util: Remove ThousandSeparate()
This is currently unused and doesn't really provide much value to keep
around either.
2018-11-13 14:04:26 -05:00
4 changed files with 40 additions and 175 deletions

View File

@@ -377,7 +377,7 @@ if (CLANG_FORMAT)
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
if (WIN32)
add_custom_target(clang-format
COMMAND powershell.exe -Command "Get-ChildItem ${SRCS}/* -Include *.cpp,*.h -Recurse | Foreach {${CLANG_FORMAT} -i $_.fullname}"
COMMAND powershell.exe -Command "${CLANG_FORMAT} -i @(Get-ChildItem -Recurse ${SRCS}/* -Include \'*.h\', \'*.cpp\')"
COMMENT ${CCOMMENT})
elseif(MINGW)
add_custom_target(clang-format

View File

@@ -4,11 +4,10 @@
#include <algorithm>
#include <cctype>
#include <cerrno>
#include <codecvt>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <locale>
#include <sstream>
#include "common/common_paths.h"
#include "common/logging/log.h"
#include "common/string_util.h"
@@ -33,24 +32,6 @@ std::string ToUpper(std::string str) {
return str;
}
// For Debugging. Read out an u8 array.
std::string ArrayToString(const u8* data, std::size_t size, int line_len, bool spaces) {
std::ostringstream oss;
oss << std::setfill('0') << std::hex;
for (int line = 0; size; ++data, --size) {
oss << std::setw(2) << (int)*data;
if (line_len == ++line) {
oss << '\n';
line = 0;
} else if (spaces)
oss << ' ';
}
return oss.str();
}
std::string StringFromBuffer(const std::vector<u8>& data) {
return std::string(data.begin(), std::find(data.begin(), data.end(), '\0'));
}
@@ -75,40 +56,6 @@ std::string StripQuotes(const std::string& s) {
return s;
}
bool TryParse(const std::string& str, u32* const output) {
char* endptr = nullptr;
// Reset errno to a value other than ERANGE
errno = 0;
unsigned long value = strtoul(str.c_str(), &endptr, 0);
if (!endptr || *endptr)
return false;
if (errno == ERANGE)
return false;
#if ULONG_MAX > UINT_MAX
if (value >= 0x100000000ull && value <= 0xFFFFFFFF00000000ull)
return false;
#endif
*output = static_cast<u32>(value);
return true;
}
bool TryParse(const std::string& str, bool* const output) {
if ("1" == str || "true" == ToLower(str))
*output = true;
else if ("0" == str || "false" == ToLower(str))
*output = false;
else
return false;
return true;
}
std::string StringFromBool(bool value) {
return value ? "True" : "False";
}

View File

@@ -5,8 +5,6 @@
#pragma once
#include <cstddef>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include "common/common_types.h"
@@ -19,44 +17,13 @@ std::string ToLower(std::string str);
/// Make a string uppercase
std::string ToUpper(std::string str);
std::string ArrayToString(const u8* data, std::size_t size, int line_len = 20, bool spaces = true);
std::string StringFromBuffer(const std::vector<u8>& data);
std::string StripSpaces(const std::string& s);
std::string StripQuotes(const std::string& s);
// Thousand separator. Turns 12345678 into 12,345,678
template <typename I>
std::string ThousandSeparate(I value, int spaces = 0) {
std::ostringstream oss;
// std::locale("") seems to be broken on many platforms
#if defined _WIN32 || (defined __linux__ && !defined __clang__)
oss.imbue(std::locale(""));
#endif
oss << std::setw(spaces) << value;
return oss.str();
}
std::string StringFromBool(bool value);
bool TryParse(const std::string& str, bool* output);
bool TryParse(const std::string& str, u32* output);
template <typename N>
static bool TryParse(const std::string& str, N* const output) {
std::istringstream iss(str);
N tmp = 0;
if (iss >> tmp) {
*output = tmp;
return true;
} else
return false;
}
std::string TabsToSpaces(int tab_size, std::string in);
void SplitString(const std::string& str, char delim, std::vector<std::string>& output);

View File

@@ -71,6 +71,10 @@ constexpr u32 PSTATE_REGISTER = 33;
constexpr u32 UC_ARM64_REG_Q0 = 34;
constexpr u32 FPCR_REGISTER = 66;
// TODO/WiP - Used while working on support for FPU
constexpr u32 TODO_DUMMY_REG_997 = 997;
constexpr u32 TODO_DUMMY_REG_998 = 998;
// For sample XML files see the GDB source /gdb/features
// GDB also wants the l character at the start
// This XML defines what the registers are for this specific ARM device
@@ -256,36 +260,6 @@ static void RegWrite(std::size_t id, u64 val, Kernel::Thread* thread = nullptr)
}
}
static u128 FpuRead(std::size_t id, Kernel::Thread* thread = nullptr) {
if (!thread) {
return u128{0};
}
auto& thread_context = thread->GetContext();
if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
return thread_context.vector_registers[id - UC_ARM64_REG_Q0];
} else if (id == FPCR_REGISTER) {
return u128{thread_context.fpcr, 0};
} else {
return u128{0};
}
}
static void FpuWrite(std::size_t id, u128 val, Kernel::Thread* thread = nullptr) {
if (!thread) {
return;
}
auto& thread_context = thread->GetContext();
if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
thread_context.vector_registers[id - UC_ARM64_REG_Q0] = val;
} else if (id == FPCR_REGISTER) {
thread_context.fpcr = val[0];
}
}
/**
* Turns hex string character into the equivalent byte.
*
@@ -435,27 +409,6 @@ static u64 GdbHexToLong(const u8* src) {
return output;
}
/**
* Convert a gdb-formatted hex string into a u128.
*
* @param src Pointer to hex string.
*/
static u128 GdbHexToU128(const u8* src) {
u128 output;
for (int i = 0; i < 16; i += 2) {
output[0] = (output[0] << 4) | HexCharToValue(src[15 - i - 1]);
output[0] = (output[0] << 4) | HexCharToValue(src[15 - i]);
}
for (int i = 0; i < 16; i += 2) {
output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i - 1]);
output[1] = (output[1] << 4) | HexCharToValue(src[16 + 15 - i]);
}
return output;
}
/// Read a byte from the gdb client.
static u8 ReadByte() {
u8 c;
@@ -646,7 +599,8 @@ static void HandleQuery() {
for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) {
const auto& threads = Core::System::GetInstance().Scheduler(core).GetThreadList();
for (const auto& thread : threads) {
val += fmt::format("{:x},", thread->GetThreadID());
val += fmt::format("{:x}", thread->GetThreadID());
val += ",";
}
}
val.pop_back();
@@ -837,15 +791,11 @@ static void ReadRegister() {
} else if (id == PSTATE_REGISTER) {
IntToGdbHex(reply, static_cast<u32>(RegRead(id, current_thread)));
} else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
u128 r = FpuRead(id, current_thread);
LongToGdbHex(reply, r[0]);
LongToGdbHex(reply + 16, r[1]);
LongToGdbHex(reply, RegRead(id, current_thread));
} else if (id == FPCR_REGISTER) {
u128 r = FpuRead(id, current_thread);
IntToGdbHex(reply, static_cast<u32>(r[0]));
} else if (id == FPCR_REGISTER + 1) {
u128 r = FpuRead(id, current_thread);
IntToGdbHex(reply, static_cast<u32>(r[0] >> 32));
LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_998, current_thread));
} else {
LongToGdbHex(reply, RegRead(TODO_DUMMY_REG_997, current_thread));
}
SendReply(reinterpret_cast<char*>(reply));
@@ -872,18 +822,13 @@ static void ReadRegisters() {
bufptr += 8;
u128 r;
for (u32 reg = UC_ARM64_REG_Q0; reg < FPCR_REGISTER; reg++) {
r = FpuRead(reg, current_thread);
LongToGdbHex(bufptr + reg * 32, r[0]);
LongToGdbHex(bufptr + reg * 32 + 16, r[1]);
for (u32 reg = UC_ARM64_REG_Q0; reg <= UC_ARM64_REG_Q0 + 31; reg++) {
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
}
bufptr += 32 * 32;
r = FpuRead(FPCR_REGISTER, current_thread);
IntToGdbHex(bufptr, static_cast<u32>(r[0]));
LongToGdbHex(bufptr, RegRead(TODO_DUMMY_REG_998, current_thread));
bufptr += 8;
@@ -908,12 +853,14 @@ static void WriteRegister() {
} else if (id == PSTATE_REGISTER) {
RegWrite(id, GdbHexToInt(buffer_ptr), current_thread);
} else if (id >= UC_ARM64_REG_Q0 && id < FPCR_REGISTER) {
FpuWrite(id, GdbHexToU128(buffer_ptr), current_thread);
RegWrite(id, GdbHexToLong(buffer_ptr), current_thread);
} else if (id == FPCR_REGISTER) {
} else if (id == FPCR_REGISTER + 1) {
RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr), current_thread);
} else {
RegWrite(TODO_DUMMY_REG_997, GdbHexToLong(buffer_ptr), current_thread);
}
// Update ARM context, skipping scheduler - no running threads at this point
// Update Unicorn context skipping scheduler, no running threads at this point
Core::System::GetInstance()
.ArmInterface(current_core)
.LoadContext(current_thread->GetContext());
@@ -938,13 +885,13 @@ static void WriteRegisters() {
} else if (reg >= UC_ARM64_REG_Q0 && reg < FPCR_REGISTER) {
RegWrite(reg, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == FPCR_REGISTER) {
RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else if (reg == FPCR_REGISTER + 1) {
RegWrite(FPCR_REGISTER, GdbHexToLong(buffer_ptr + i * 16), current_thread);
RegWrite(TODO_DUMMY_REG_998, GdbHexToLong(buffer_ptr + i * 16), current_thread);
} else {
UNIMPLEMENTED();
}
}
// Update ARM context, skipping scheduler - no running threads at this point
// Update Unicorn context skipping scheduler, no running threads at this point
Core::System::GetInstance()
.ArmInterface(current_core)
.LoadContext(current_thread->GetContext());
@@ -970,6 +917,12 @@ static void ReadMemory() {
SendReply("E01");
}
const auto& vm_manager = Core::CurrentProcess()->VMManager();
if (addr < vm_manager.GetCodeRegionBaseAddress() ||
addr >= vm_manager.GetMapRegionEndAddress()) {
return SendReply("E00");
}
if (!Memory::IsValidVirtualAddress(addr)) {
return SendReply("E00");
}
@@ -1014,7 +967,7 @@ void Break(bool is_memory_break) {
static void Step() {
if (command_length > 1) {
RegWrite(PC_REGISTER, GdbHexToLong(command_buffer + 1), current_thread);
// Update ARM context, skipping scheduler - no running threads at this point
// Update Unicorn context skipping scheduler, no running threads at this point
Core::System::GetInstance()
.ArmInterface(current_core)
.LoadContext(current_thread->GetContext());
@@ -1057,7 +1010,7 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) {
breakpoint.addr = addr;
breakpoint.len = len;
Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size());
static constexpr std::array<u8, 4> btrap{0x00, 0x7d, 0x20, 0xd4};
static constexpr std::array<u8, 4> btrap{{0x00, 0x7d, 0x20, 0xd4}};
Memory::WriteBlock(addr, btrap.data(), btrap.size());
Core::System::GetInstance().InvalidateCpuInstructionCaches();
p.insert({addr, breakpoint});
@@ -1368,15 +1321,13 @@ void SetCpuStepFlag(bool is_step) {
}
void SendTrap(Kernel::Thread* thread, int trap) {
if (!send_trap) {
return;
if (send_trap) {
if (!halt_loop || current_thread == thread) {
current_thread = thread;
SendSignal(thread, trap);
}
halt_loop = true;
send_trap = false;
}
if (!halt_loop || current_thread == thread) {
current_thread = thread;
SendSignal(thread, trap);
}
halt_loop = true;
send_trap = false;
}
}; // namespace GDBStub