summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/FreeBSD
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-11-19 20:06:13 +0000
commitc0981da47d5696fe36474fcf86b4ce03ae3ff818 (patch)
treef42add1021b9f2ac6a69ac7cf6c4499962739a45 /lldb/source/Plugins/Process/FreeBSD
parent344a3780b2e33f6ca763666c380202b18aab72a3 (diff)
Diffstat (limited to 'lldb/source/Plugins/Process/FreeBSD')
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp41
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h2
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp58
-rw-r--r--lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h5
4 files changed, 100 insertions, 6 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
index d6426b3d2367..a62d3c1ba052 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp
@@ -130,8 +130,12 @@ NativeProcessFreeBSD::Factory::Attach(
NativeProcessFreeBSD::Extension
NativeProcessFreeBSD::Factory::GetSupportedExtensions() const {
- return Extension::multiprocess | Extension::fork | Extension::vfork |
- Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
+ return
+#if defined(PT_COREDUMP)
+ Extension::savecore |
+#endif
+ Extension::multiprocess | Extension::fork | Extension::vfork |
+ Extension::pass_signals | Extension::auxv | Extension::libraries_svr4;
}
// Public Instance Methods
@@ -1009,3 +1013,36 @@ void NativeProcessFreeBSD::MonitorClone(::pid_t child_pid, bool is_vfork,
}
}
}
+
+llvm::Expected<std::string>
+NativeProcessFreeBSD::SaveCore(llvm::StringRef path_hint) {
+#if defined(PT_COREDUMP)
+ using namespace llvm::sys::fs;
+
+ llvm::SmallString<128> path{path_hint};
+ Status error;
+ struct ptrace_coredump pc = {};
+
+ // Try with the suggested path first. If there is no suggested path or it
+ // failed to open, use a temporary file.
+ if (path.empty() ||
+ openFile(path, pc.pc_fd, CD_CreateNew, FA_Write, OF_None)) {
+ if (std::error_code errc =
+ createTemporaryFile("lldb", "core", pc.pc_fd, path))
+ return llvm::createStringError(errc, "Unable to create a temporary file");
+ }
+ error = PtraceWrapper(PT_COREDUMP, GetID(), &pc, sizeof(pc));
+
+ std::error_code close_err = closeFile(pc.pc_fd);
+ if (error.Fail())
+ return error.ToError();
+ if (close_err)
+ return llvm::createStringError(
+ close_err, "Unable to close the core dump after writing");
+ return path.str().str();
+#else // !defined(PT_COREDUMP)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "PT_COREDUMP not supported in the FreeBSD version used to build LLDB");
+#endif
+}
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
index 7ec9d17d4cf4..44b8a53699bb 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h
@@ -91,6 +91,8 @@ public:
bool SupportHardwareSingleStepping() const;
+ llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) override;
+
protected:
llvm::Expected<llvm::ArrayRef<uint8_t>>
GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
index 8e722c09314c..d93b7fd33815 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
@@ -15,6 +15,7 @@
#include "lldb/Utility/Status.h"
#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"
// clang-format off
#include <sys/param.h>
@@ -59,11 +60,32 @@ uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {
return count;
}
+llvm::Optional<NativeRegisterContextFreeBSD_mips64::RegSetKind>
+NativeRegisterContextFreeBSD_mips64::GetSetForNativeRegNum(
+ uint32_t reg_num) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::mips64:
+ if (reg_num >= k_first_gpr_mips64 && reg_num <= k_last_gpr_mips64)
+ return GPRegSet;
+ if (reg_num >= k_first_fpr_mips64 && reg_num <= k_last_fpr_mips64)
+ return FPRegSet;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ llvm_unreachable("Register does not belong to any register set");
+}
+
Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) {
switch (set) {
case GPRegSet:
return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + GetRegisterInfo().GetGPRSize());
}
llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");
}
@@ -73,6 +95,10 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) {
case GPRegSet:
return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_SETFPREGS, m_thread.GetID(),
+ m_reg_data.data() + GetRegisterInfo().GetGPRSize());
}
llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");
}
@@ -94,7 +120,16 @@ NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,
? reg_info->name
: "<unknown register>");
- RegSetKind set = GPRegSet;
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
error = ReadRegisterSet(set);
if (error.Fail())
return error;
@@ -119,7 +154,16 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister(
? reg_info->name
: "<unknown register>");
- RegSetKind set = GPRegSet;
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
error = ReadRegisterSet(set);
if (error.Fail())
return error;
@@ -139,6 +183,10 @@ Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(
if (error.Fail())
return error;
+ error = ReadRegisterSet(FPRegSet);
+ if (error.Fail())
+ return error;
+
data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
uint8_t *dst = data_sp->GetBytes();
::memcpy(dst, m_reg_data.data(), m_reg_data.size());
@@ -175,7 +223,11 @@ Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(
}
::memcpy(m_reg_data.data(), src, m_reg_data.size());
- return WriteRegisterSet(GPRegSet);
+ error = WriteRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(FPRegSet);
}
llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(
diff --git a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
index 6a3eb86a9231..8e300ed829c9 100644
--- a/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
+++ b/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.h
@@ -54,8 +54,11 @@ public:
private:
enum RegSetKind {
GPRegSet,
+ FPRegSet,
};
- std::array<uint8_t, sizeof(reg)> m_reg_data;
+ std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+
+ llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
Status ReadRegisterSet(RegSetKind set);
Status WriteRegisterSet(RegSetKind set);