blob: 268ccb0d58f651bbc5a10852571cd09e43f5430d [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/client/breakpoint_settings.h"
#include "src/developer/debug/ipc/protocol.h"
#include "src/developer/debug/zxdb/client/setting_schema_definition.h"
namespace zxdb {
// static
const char* BreakpointSettings::StopModeToString(StopMode stop_mode) {
switch (stop_mode) {
case BreakpointSettings::StopMode::kNone:
return ClientSettings::Breakpoint::kStopMode_None;
case BreakpointSettings::StopMode::kThread:
return ClientSettings::Breakpoint::kStopMode_Thread;
case BreakpointSettings::StopMode::kProcess:
return ClientSettings::Breakpoint::kStopMode_Process;
case BreakpointSettings::StopMode::kAll:
return ClientSettings::Breakpoint::kStopMode_All;
}
return "<invalid>";
}
// static
std::optional<BreakpointSettings::StopMode> BreakpointSettings::StringToStopMode(
std::string_view value) {
if (value == ClientSettings::Breakpoint::kStopMode_None) {
return BreakpointSettings::StopMode::kNone;
} else if (value == ClientSettings::Breakpoint::kStopMode_Thread) {
return BreakpointSettings::StopMode::kThread;
} else if (value == ClientSettings::Breakpoint::kStopMode_Process) {
return BreakpointSettings::StopMode::kProcess;
} else if (value == ClientSettings::Breakpoint::kStopMode_All) {
return BreakpointSettings::StopMode::kAll;
}
return std::nullopt;
}
// static
const char* BreakpointSettings::TypeToString(BreakpointSettings::Type t) {
switch (t) {
case BreakpointSettings::Type::kSoftware:
return ClientSettings::Breakpoint::kType_Software;
case BreakpointSettings::Type::kHardware:
return ClientSettings::Breakpoint::kType_Hardware;
case BreakpointSettings::Type::kReadWrite:
return ClientSettings::Breakpoint::kType_ReadWrite;
case BreakpointSettings::Type::kWrite:
return ClientSettings::Breakpoint::kType_Write;
case BreakpointSettings::Type::kLast:
break; // Not valid.
}
FX_NOTREACHED();
return "<invalid>";
}
// static
std::optional<BreakpointSettings::Type> BreakpointSettings::StringToType(std::string_view value) {
if (value == ClientSettings::Breakpoint::kType_Software) {
return BreakpointSettings::Type::kSoftware;
} else if (value == ClientSettings::Breakpoint::kType_Hardware) {
return BreakpointSettings::Type::kHardware;
} else if (value == ClientSettings::Breakpoint::kType_ReadWrite) {
return BreakpointSettings::Type::kReadWrite;
} else if (value == ClientSettings::Breakpoint::kType_Write) {
return BreakpointSettings::Type::kWrite;
}
return std::nullopt;
}
// static
bool BreakpointSettings::TypeHasSize(Type t) { return t == Type::kReadWrite || t == Type::kWrite; }
// static
Err BreakpointSettings::ValidateSize(debug::Arch arch, Type type, uint32_t byte_size) {
// Note that "arch" may be kUnknown at this point if the user is making a breakpoint before
// connecting. That should be OK and weaker validation should be done.
if (!TypeHasSize(type)) {
if (byte_size != 0) {
return Err("Breakpoints of type '%s' don't have sizes associated with them.",
TypeToString(type));
}
return Err();
}
// All hardware breakpoints have a size.
if (arch == debug::Arch::kX64 && type == Type::kHardware) {
// x64 only supports 1-byte hardware execution breakpoints.
if (byte_size != 1)
return Err("Intel CPUs only support hardware execution breakpoints of 1 byte.");
return Err();
}
// Our backend on all platforms currently supports only 1, 2, 4, and 8 byte hardware breakpoints
// for all other cases.
if (byte_size != 1 && byte_size != 2 && byte_size != 4 && byte_size != 8) {
return Err(
"Hardware breakpoints must be 1, 2, 4, or 8 bytes long only. If you need a\n"
"slightly longer one, you can create several adjacent 8-byte ones, but there\n"
"are a limited number of hardware breakpoints supported by the CPU.");
}
return Err();
}
} // namespace zxdb