pkgsrc-WIP-changes archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
edb-debugger-git: Porting to NetBSD in progress
Module Name: pkgsrc-wip
Committed By: Kamil Rytarowski <n54%gmx.com@localhost>
Pushed By: kamil
Date: Sun Feb 19 06:48:54 2017 +0100
Changeset: 3cce6f2d819f1aaeb1a3a89aad6206d8538f2b03
Modified Files:
edb-debugger-git/distinfo
edb-debugger-git/patches/patch-CMakeLists.txt
edb-debugger-git/patches/patch-include_os_unix_netbsd_linker.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp
edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h
Log Message:
edb-debugger-git: Porting to NetBSD in progress
To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=3cce6f2d819f1aaeb1a3a89aad6206d8538f2b03
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
diffstat:
edb-debugger-git/distinfo | 42 +-
edb-debugger-git/patches/patch-CMakeLists.txt | 11 +-
.../patches/patch-include_os_unix_netbsd_linker.h | 2 +-
...ugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp | 295 ++------
...plugins_DebuggerCore_unix_netbsd_DebuggerCore.h | 2 +-
...DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp | 2 +-
...s_DebuggerCore_unix_netbsd_DialogMemoryAccess.h | 2 +-
..._DebuggerCore_unix_netbsd_DialogMemoryAccess.ui | 2 +-
...gins_DebuggerCore_unix_netbsd_FeatureDetect.cpp | 2 +-
...lugins_DebuggerCore_unix_netbsd_FeatureDetect.h | 2 +-
...ins_DebuggerCore_unix_netbsd_PlatformCommon.cpp | 2 +-
...ugins_DebuggerCore_unix_netbsd_PlatformCommon.h | 2 +-
...gins_DebuggerCore_unix_netbsd_PlatformEvent.cpp | 310 +++++++--
...lugins_DebuggerCore_unix_netbsd_PlatformEvent.h | 55 +-
...ns_DebuggerCore_unix_netbsd_PlatformProcess.cpp | 752 ++++++++++++++++++++-
...gins_DebuggerCore_unix_netbsd_PlatformProcess.h | 60 +-
...ins_DebuggerCore_unix_netbsd_PlatformRegion.cpp | 2 +-
...ugins_DebuggerCore_unix_netbsd_PlatformRegion.h | 2 +-
...gins_DebuggerCore_unix_netbsd_PlatformState.cpp | 2 +-
...lugins_DebuggerCore_unix_netbsd_PlatformState.h | 2 +-
...ins_DebuggerCore_unix_netbsd_PlatformThread.cpp | 2 +-
...ugins_DebuggerCore_unix_netbsd_PlatformThread.h | 2 +-
22 files changed, 1190 insertions(+), 365 deletions(-)
diffs:
diff --git a/edb-debugger-git/distinfo b/edb-debugger-git/distinfo
index 642f3d5fef..c398073feb 100644
--- a/edb-debugger-git/distinfo
+++ b/edb-debugger-git/distinfo
@@ -4,31 +4,31 @@ SHA1 (edb-debugger-0.9.21.tar.gz) = eff050b5ec53f02ebc96dbbb80f1731036e2c6f6
RMD160 (edb-debugger-0.9.21.tar.gz) = d7821e07b607667090b1158b559053856ef077de
SHA512 (edb-debugger-0.9.21.tar.gz) = 88a04cafb2c27a3af6bcfc48c841c795fb5bba348f64fe52957716c2c03e4cd056d045b241135c5be7fd7174d2c5a35fa5c95dc2b6aad4fb5c04f4fe36ab4f0d
Size (edb-debugger-0.9.21.tar.gz) = 996932 bytes
-SHA1 (patch-CMakeLists.txt) = d714177643b1f8b3a37c8d6bd51953c5fb296239
+SHA1 (patch-CMakeLists.txt) = 8f64b4aa123f8d5007116ddec3e1bfcfa82f0cd8
SHA1 (patch-include_os_unix_OSTypes.h) = 8209e8cd487b4b93532847df9166c0abecb00c48
-SHA1 (patch-include_os_unix_netbsd_linker.h) = d09a31187b4e7c0d4a20db6c32806cc8fd710538
+SHA1 (patch-include_os_unix_netbsd_linker.h) = 3331bd1eae1cd401df8b1b18ce86ae228fd0df6b
SHA1 (patch-plugins_Analyzer_Analyzer.cpp) = 511efa03a82a96612d64fd43b9e6631e4d6aeb76
SHA1 (patch-plugins_Assembler_DialogAssembler.cpp) = 2bd6418dc078aae0c84c6092f15619e202e43b31
SHA1 (patch-plugins_DebuggerCore_CMakeLists.txt) = 18b3f0bd7c7c7ec4eaa6526c81b7c4299c7ee3f4
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp) = 716e48cbe859d12cd31a50040fc556e4f26fd659
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h) = 6dc06aa1d0d05741cce3f8cffbee5d0c3c377be3
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp) = 5096c5fc7b1812545faf70194b1d02985fc1546f
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h) = 390ce937f71b3b4c5c63dd668dc42115d2e0622c
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui) = fb6689928090b65e3cb6f6e69886199a447c2fa6
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp) = d7a577e879e30447122985e09609cc195670157f
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h) = 4e5a8906e904d76f4fa85a5e1919a37f57083d1e
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp) = b1b07940d1a717ffd24ccd4bb028c098e5a6a8b6
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h) = 7431b033535e272689814eb7647043aa5c9282c1
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp) = 62e99fc234d072fa4ba82435216349eb76af2076
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h) = 1781ca113c68b2e88051c7bf49bf388f61169ece
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp) = 06bc435f25546ef3f27cf60ba815f7dc9d8f9706
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h) = a4ddbd5c6f486695d4de27954ed65de4ec8bb288
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp) = dc5b3caa442e041658da7aac8e59d51ccfe0c130
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h) = 89533d8d73b58fa035832a3aaa302591ab03016e
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp) = 347599efb4564a0bfac204108baa58032ea9415f
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h) = 289f37da62a14eee3fc50c38812b202430701887
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp) = e3fb003a591a6e9134b4e638307c9c202846c152
-SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h) = bb93f03d6290c894ce543d2ea51f5023093a0fa3
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp) = 8800bc3d376aadc0ece903d8e0d5af3ab8c1f469
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h) = c5572bd8844097e1e98b9dc39d27e93eaf764027
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp) = 07f547f9fc9155718fe4e84eb7ec6a057596ff0d
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h) = e0c17871f6151de55415c355e1645c0c92d663f8
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui) = 8bacf6231f3cbc5db78ad7dbf1c191c28e94a85e
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp) = a85e0e1df2ea02d3992fcb9ba3706c7a3e730442
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h) = 58d8275733116887d66b9dbda5085b8acc2f68c3
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp) = c6a0a101f2de0df887c32b04dbcbcc6b55117e88
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h) = c696b28b1504ad63c39adcb09cf339b48578aab1
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp) = 6e0e3f0d73fc90caafc260e74f6b14594fcc8565
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h) = ae2b926f5f3a17c40f7008b0a9deaf146f3831a4
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp) = 138df2d61e9f9321be716d3ec4d1f852c6a8bc6d
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h) = afc6a7034720924a0a3d31cc92585f15310fa454
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp) = 454dc33e2afd41f4a2b7e7218beb187c7585daaf
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h) = 6d012fe9c687b920a300824c60a10cd2c2eaac5c
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp) = 7e22120e55b5f2c206c71899eb02047790f4b4a1
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h) = 9d2edb758a0de34261960e407f91305261fd5ad0
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp) = d0bbc698352e9361b9ba6c26d09b220b196bf4b5
+SHA1 (patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h) = b557502699a7b9053f09732708b5a2b2050b5d1c
SHA1 (patch-plugins_HeapAnalyzer_DialogHeap.cpp) = a11c5aeb91168f4bf2f58fa35137fec2d5107ea4
SHA1 (patch-plugins_ProcessProperties_DialogProcessProperties.cpp) = 31d9915e63a963fdd597dc141e3424fa8f05e81b
SHA1 (patch-src_Debugger.cpp) = 3e0c929169c464f3697b28a5f00c1b8e877c7da3
diff --git a/edb-debugger-git/patches/patch-CMakeLists.txt b/edb-debugger-git/patches/patch-CMakeLists.txt
index 7592cec35e..f6d074be3c 100644
--- a/edb-debugger-git/patches/patch-CMakeLists.txt
+++ b/edb-debugger-git/patches/patch-CMakeLists.txt
@@ -1,7 +1,16 @@
$NetBSD$
---- CMakeLists.txt.orig 2017-02-19 00:51:34.453399346 +0000
+--- CMakeLists.txt.orig 2017-02-18 21:21:09.000000000 +0000
+++ CMakeLists.txt
+@@ -12,7 +12,7 @@ if (NOT QT_VERSION)
+ SET_PROPERTY(CACHE QT_VERSION PROPERTY STRINGS Qt5 Qt4)
+ endif()
+
+-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "{PROJECT_SOURCE_DIR}/cmake/Modules/")
++set (CMAKE_MODULE_PATH "/tmp/pkgsrc-tmp/wip/edb-debugger-git/work/.buildlink/cmake-Modules" ${CMAKE_MODULE_PATH} "{PROJECT_SOURCE_DIR}/cmake/Modules/")
+
+ include("GNUInstallDirs")
+
@@ -52,6 +52,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux"
include_directories("include/os/unix/linux")
endif()
diff --git a/edb-debugger-git/patches/patch-include_os_unix_netbsd_linker.h b/edb-debugger-git/patches/patch-include_os_unix_netbsd_linker.h
index fdaf4c8ca4..5b0b0ac777 100644
--- a/edb-debugger-git/patches/patch-include_os_unix_netbsd_linker.h
+++ b/edb-debugger-git/patches/patch-include_os_unix_netbsd_linker.h
@@ -1,6 +1,6 @@
$NetBSD$
---- include/os/unix/netbsd/linker.h.orig 2017-02-19 00:51:04.539051677 +0000
+--- include/os/unix/netbsd/linker.h.orig 2017-02-19 02:09:05.286832064 +0000
+++ include/os/unix/netbsd/linker.h
@@ -0,0 +1,52 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp
index d4f570d5c4..d1441a6346 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.cpp
@@ -1,8 +1,8 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/DebuggerCore.cpp.orig 2017-02-19 00:51:04.557463589 +0000
+--- plugins/DebuggerCore/unix/netbsd/DebuggerCore.cpp.orig 2017-02-19 02:09:05.311209498 +0000
+++ plugins/DebuggerCore/unix/netbsd/DebuggerCore.cpp
-@@ -0,0 +1,760 @@
+@@ -0,0 +1,593 @@
+/*
+Copyright (C) 2006 - 2015 Evan Teran
+ evan.teran%gmail.com@localhost
@@ -45,10 +45,14 @@ $NetBSD$
+#include <cerrno>
+#include <cstring>
+
-+#include <cpuid.h>
++#include <sys/param.h>
++#include <sys/types.h>
++#include <sys/sysctl.h>
+#include <sys/ptrace.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
++#include <cpuid.h>
++
+#include <unistd.h>
+
+namespace DebuggerCorePlugin {
@@ -236,45 +240,14 @@ $NetBSD$
+
+ auto e = std::make_shared<PlatformEvent>();
+
-+ e->pid_ = pid();
-+ e->tid_ = tid;
++ e->pid_ = pid;
+ e->status_ = status;
-+ ptrace_getsiginfo(tid, &e->siginfo_);
++ ptrace_getsiginfo(pid, &e->siginfo_);
+
+ return e;
+}
+
+//------------------------------------------------------------------------------
-+// Name: stop_threads
-+// Desc:
-+//------------------------------------------------------------------------------
-+void DebuggerCore::stop_threads() {
-+ if(process_) {
-+ for(auto &thread: process_->threads()) {
-+ const edb::tid_t tid = thread->tid();
-+
-+ if(!waited_threads_.contains(tid)) {
-+
-+ if(auto thread_ptr = std::static_pointer_cast<PlatformThread>(thread)) {
-+
-+ thread->stop();
-+
-+ int thread_status;
-+ if(native::waitpid(tid, &thread_status, __WALL) > 0) {
-+ waited_threads_.insert(tid);
-+ thread_ptr->status_ = thread_status;
-+
-+ if(!WIFSTOPPED(thread_status) || WSTOPSIG(thread_status) != SIGSTOP) {
-+ qDebug("stop_threads(): [warning] paused thread [%d] received an event besides SIGSTOP: status=0x%x", tid,thread_status);
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+//------------------------------------------------------------------------------
+// Name: wait_debug_event
+// Desc: waits for a debug event, msecs is a timeout
+// it will return false if an error or timeout occurs
@@ -284,9 +257,9 @@ $NetBSD$
+ if(process_) {
+ if(!native::wait_for_sigchld(msecs)) {
+ int status;
-+ const edb::pid_t pid = native::waitpid(thread->tid(), &status, __WALL | WNOHANG);
-+ if(pid > 0) {
-+ return handle_event(tid, status);
++ const edb::pid_t wpid = native::waitpid(pid(), &status, __WALL | WNOHANG);
++ if(wpid > 0) {
++ return handle_event(pid(), status);
+ }
+ }
+ }
@@ -294,46 +267,6 @@ $NetBSD$
+}
+
+//------------------------------------------------------------------------------
-+// Name: attach_thread
-+// Desc: returns 0 if successful, errno if failed
-+//------------------------------------------------------------------------------
-+int DebuggerCore::attach_thread(edb::tid_t tid) {
-+ if(ptrace(PTRACE_ATTACH, tid, 0, 0) == 0) {
-+ // I *think* that the PTRACE_O_TRACECLONE is only valid on
-+ // stopped threads
-+ int status;
-+ const auto ret=native::waitpid(tid, &status, __WALL);
-+ if(ret > 0) {
-+
-+ auto newThread = std::make_shared<PlatformThread>(this, process_, tid);
-+ newThread->status_ = status;
-+ newThread->signal_status_ = PlatformThread::Stopped;
-+
-+ threads_[tid] = newThread;
-+
-+ waited_threads_.insert(tid);
-+ if(ptrace_set_options(tid, PTRACE_O_TRACECLONE) == -1) {
-+ qDebug("[DebuggerCore] failed to set PTRACE_O_TRACECLONE: [%d] %s", tid, strerror(errno));
-+ }
-+
-+ if(edb::v1::config().close_behavior==Configuration::Kill ||
-+ (edb::v1::config().close_behavior==Configuration::KillIfLaunchedDetachIfAttached &&
-+ last_means_of_capture()==MeansOfCapture::Launch)) {
-+ if(ptrace_set_options(tid, PTRACE_O_EXITKILL) == -1) {
-+ qDebug("[DebuggerCore] failed to set PTRACE_O_EXITKILL: [%d] %s", tid, strerror(errno));
-+ }
-+ }
-+ return 0;
-+ }
-+ else if(ret==-1) {
-+ return errno;
-+ }
-+ else return -1; // unknown error
-+ }
-+ else return errno;
-+}
-+
-+//------------------------------------------------------------------------------
+// Name: attach
+// Desc:
+//------------------------------------------------------------------------------
@@ -348,41 +281,13 @@ $NetBSD$
+ // create this, so the threads created can refer to it
+ process_ = new PlatformProcess(this, pid);
+
-+ int lastErr=attach_thread(pid); // Fail early if we are going to
++ int lastErr=ptrace(PT_ATTACH, pid, NULL, 0); // Fail early if we are going to
+ if(lastErr) return std::strerror(lastErr);
-+ lastErr=-2;
-+ bool attached;
-+ do {
-+ attached = false;
-+ QDir proc_directory(QString("/proc/%1/task/").arg(pid));
-+ for(const QString &s: proc_directory.entryList(QDir::NoDotAndDotDot | QDir::Dirs)) {
-+ // this can get tricky if the threads decide to spawn new threads
-+ // when we are attaching. I wish that linux had an atomic way to do this
-+ // all in one shot
-+ const edb::tid_t tid = s.toUInt();
-+ if(!threads_.contains(tid)) {
-+ const auto errnum=attach_thread(tid);
-+ if(errnum==0)
-+ attached = true;
-+ else
-+ lastErr=errnum;
-+ }
-+ }
-+ } while(attached);
-+
-+
-+ if(!threads_.empty()) {
-+ pid_ = pid;
-+ active_thread_ = pid;
-+ binary_info_ = edb::v1::get_binary_info(edb::v1::primary_code_region());
-+ detectDebuggeeBitness();
-+ return statusOK;
-+ } else {
-+ delete process_;
-+ process_ = nullptr;
-+ }
+
-+ return std::strerror(lastErr);
++ pid_ = pid;
++ binary_info_ = edb::v1::get_binary_info(edb::v1::primary_code_region());
++ detectDebuggeeBitness();
++ return statusOK;
+}
+
+//------------------------------------------------------------------------------
@@ -392,13 +297,9 @@ $NetBSD$
+void DebuggerCore::detach() {
+ if(process_) {
+
-+ stop_threads();
-+
+ clear_breakpoints();
+
-+ for(auto thread: process_->threads()) {
-+ ptrace(PTRACE_DETACH, thread->tid(), 0, 0);
-+ }
++ ptrace(PT_DETACH, pid(), NULL, 0);
+
+ delete process_;
+ process_ = nullptr;
@@ -415,9 +316,8 @@ $NetBSD$
+ if(attached()) {
+ clear_breakpoints();
+
-+ ::kill(pid(), SIGKILL);
++ ptrace(PT_KILL, pid(), NULL, 0);
+
-+ // TODO: do i need to actually do this wait?
+ native::waitpid(pid(), 0, __WALL);
+
+ delete process_;
@@ -428,56 +328,15 @@ $NetBSD$
+}
+
+void DebuggerCore::detectDebuggeeBitness() {
-+
-+ const size_t offset=EDB_IS_64_BIT ?
-+ offsetof(UserRegsStructX86_64, cs) :
-+ offsetof(UserRegsStructX86, xcs);
-+ errno=0;
-+ const edb::seg_reg_t cs=ptrace(PTRACE_PEEKUSER, active_thread_, offset, 0);
-+ if(!errno) {
-+ if(cs==USER_CS_32) {
-+ if(pointer_size_==sizeof(quint64)) {
-+ qDebug() << "Debuggee is now 32 bit";
-+ CapstoneEDB::init(CapstoneEDB::Architecture::ARCH_X86);
-+ }
-+ pointer_size_=sizeof(quint32);
-+ return;
-+ } else if(cs==USER_CS_64) {
-+ if(pointer_size_==sizeof(quint32)) {
-+ qDebug() << "Debuggee is now 64 bit";
-+ CapstoneEDB::init(CapstoneEDB::Architecture::ARCH_AMD64);
-+ }
-+ pointer_size_=sizeof(quint64);
-+ return;
-+ }
-+ }
-+}
-+
-+//------------------------------------------------------------------------------
-+// Name: get_state
-+// Desc:
-+//------------------------------------------------------------------------------
-+void DebuggerCore::get_state(State *state) {
-+ // TODO: assert that we are paused
-+ if(process_) {
-+ if(IThread::pointer thread = process_->current_thread()) {
-+ thread->get_state(state);
-+ }
-+ }
-+}
-+
-+//------------------------------------------------------------------------------
-+// Name: set_state
-+// Desc:
-+//------------------------------------------------------------------------------
-+void DebuggerCore::set_state(const State &state) {
-+
-+ // TODO: assert that we are paused
-+ if(process_) {
-+ if(IThread::pointer thread = process_->current_thread()) {
-+ thread->set_state(state);
-+ }
-+ }
++#if defined(__i386__)
++ qDebug() << "Debuggee is now 32 bit";
++ CapstoneEDB::init(CapstoneEDB::Architecture::ARCH_X86);
++#elif defined(__x86_64__)
++ qDebug() << "Debuggee is now 64 bit";
++ CapstoneEDB::init(CapstoneEDB::Architecture::ARCH_AMD64);
++#else
++#error portme
++#endif
+}
+
+//------------------------------------------------------------------------------
@@ -492,7 +351,7 @@ $NetBSD$
+
+ lastMeansOfCapture=MeansOfCapture::Launch;
+
-+ static constexpr std::size_t sharedMemSize=4096;
++ static std::size_t sharedMemSize=getpagesize();
+ const auto sharedMem=static_cast<QChar*>(::mmap(nullptr,sharedMemSize,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0));
+ std::memset(sharedMem,0,sharedMemSize);
+
@@ -515,24 +374,9 @@ $NetBSD$
+ Q_UNUSED(std_err);
+ }
+
-+ if(edb::v1::config().disableASLR) {
-+ const auto curPers=::personality(UINT32_MAX);
-+ // This shouldn't fail, but let's at least perror if it does anyway
-+ if(curPers==-1)
-+ perror("Failed to get current personality");
-+ else if(::personality(curPers|ADDR_NO_RANDOMIZE)==-1)
-+ perror("Failed to disable ASLR");
-+ }
-+
-+ if(edb::v1::config().disableLazyBinding && setenv("LD_BIND_NOW","1",true)==-1)
-+ perror("Failed to disable lazy binding");
-+
+ // do the actual exec
+ const QString error=execute_process(path, cwd, args);
-+#if defined __GNUG__ && __GNUC__ >= 5 || !defined __GNUG__ || \
-+ defined __clang__ && __clang_major__*100+__clang_minor__>=306
+ static_assert(std::is_trivially_copyable<QChar>::value,"Can't copy string of QChar to shared memory");
-+#endif
+ std::memcpy(sharedMem,error.constData(),std::min(sizeof(QChar)*error.size(),sharedMemSize-sizeof(QChar)/*prevent overwriting of last null*/));
+
+ // we should never get here!
@@ -572,40 +416,10 @@ $NetBSD$
+ .arg(status,0,16)+(childError.isEmpty()?"":QObject::tr(".\nError returned by child:\n%1.").arg(childError));
+ }
+
-+ waited_threads_.insert(pid);
-+
-+ // enable following clones (threads)
-+ if(ptrace_set_options(pid, PTRACE_O_TRACECLONE) == -1) {
-+ const auto strerr=strerror(errno); // NOTE: must be called before end_debug_session, otherwise errno can change
-+ end_debug_session();
-+ return QObject::tr("[DebuggerCore] failed to set PTRACE_O_TRACECLONE: %1").arg(strerr);
-+ }
-+
-+#ifdef PTRACE_O_EXITKILL
-+ if(ptrace_set_options(pid, PTRACE_O_EXITKILL) == -1) {
-+ const auto strerr=strerror(errno); // NOTE: must be called before any other syscall, otherwise errno can change
-+ // Don't consider the error fatal: the option is only supported since Linux 3.8
-+ qDebug() << "[DebuggerCore] failed to set PTRACE_O_EXITKILL:" << strerr;
-+ }
-+#endif
-+
-+ // setup the first event data for the primary thread
-+ waited_threads_.insert(pid);
-+
+ // create the process
+ process_ = new PlatformProcess(this, pid);
+
-+
-+ // the PID == primary TID
-+ auto newThread = std::make_shared<PlatformThread>(this, process_, pid);
-+ newThread->status_ = status;
-+ newThread->signal_status_ = PlatformThread::Stopped;
-+
-+ threads_[pid] = newThread;
-+
+ pid_ = pid;
-+ active_thread_ = pid;
-+ binary_info_ = edb::v1::get_binary_info(edb::v1::primary_code_region());
+
+ detectDebuggeeBitness();
+
@@ -630,10 +444,7 @@ $NetBSD$
+//------------------------------------------------------------------------------
+void DebuggerCore::reset() {
+ threads_.clear();
-+ waited_threads_.clear();
+ pid_ = 0;
-+ active_thread_ = 0;
-+ binary_info_ = nullptr;
+}
+
+//------------------------------------------------------------------------------
@@ -651,22 +462,44 @@ $NetBSD$
+QMap<edb::pid_t, IProcess::pointer> DebuggerCore::enumerate_processes() const {
+ QMap<edb::pid_t, IProcess::pointer> ret;
+
-+ QDir proc_directory("/proc/");
-+ QFileInfoList entries = proc_directory.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
-+
-+ for(const QFileInfo &info: entries) {
-+ const QString filename = info.fileName();
-+ if(is_numeric(filename)) {
-+ const edb::pid_t pid = filename.toULong();
++ int err;
++ ::kinfo_proc2 *result;
++ int mib[6];
++ size_t length = 0;
++
++ mib[0] = CTL_KERN;
++ mib[1] = KERN_PROC2;
++ mib[2] = KERN_PROC_ALL;
++ mib[3] = 0;
++ mib[4] = sizeof(struct kinfo_proc2);
++retry:
++ mib[5] = 0;
++
++ err = sysctl(mib, __arraycount(mib), NULL, &length, NULL, 0);
++ if (err == -1)
++ return ret;
++
++ result = (::kinfo_proc2 *)malloc(length);
++ if (result == NULL)
++ return ret;
++
++ mib[5] = length / sizeof(struct kinfo_proc2);
++ err = sysctl(mib, __arraycount(mib), result, &length, NULL, 0);
++ if (err == -1) {
++ if (errno == ENOMEM)
++ goto retry;
++
++ free(result);
++ return ret;
++ }
+
-+ // NOTE(eteran): the const_cast is reasonable here.
-+ // While we don't want THIS function to mutate the DebuggerCore object
-+ // we do want the associated PlatformProcess to be able to trigger
-+ // non-const operations in the future, at least hypothetically.
-+ ret.insert(pid, std::make_shared<PlatformProcess>(const_cast<DebuggerCore*>(this), pid));
-+ }
++ for (size_t i = 0; i < length / sizeof(kinfo_proc2); i++) {
++ const edb::pid_t pid = result[i].p_pid;
++ ret.insert(pid, std::make_shared<PlatformProcess>(const_cast<DebuggerCore*>(this), pid));
+ }
+
++ free(result);
++
+ return ret;
+}
+
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h
index eefd58e805..a5621ad443 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DebuggerCore.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/DebuggerCore.h.orig 2017-02-19 00:51:04.563698490 +0000
+--- plugins/DebuggerCore/unix/netbsd/DebuggerCore.h.orig 2017-02-19 02:09:05.317531286 +0000
+++ plugins/DebuggerCore/unix/netbsd/DebuggerCore.h
@@ -0,0 +1,119 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp
index 2ab9500e88..276b07ad42 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.cpp.orig 2017-02-19 00:51:04.569868074 +0000
+--- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.cpp.orig 2017-02-19 02:09:05.323748418 +0000
+++ plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.cpp
@@ -0,0 +1,38 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h
index 4d90a800ca..1f221ff206 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.h.orig 2017-02-19 00:51:04.575933251 +0000
+--- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.h.orig 2017-02-19 02:09:05.329914385 +0000
+++ plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.h
@@ -0,0 +1,44 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui
index 987b9770e3..b7f292b8c0 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_DialogMemoryAccess.ui
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.ui.orig 2017-02-19 01:11:03.492521515 +0000
+--- plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.ui.orig 2017-02-19 02:09:05.336211780 +0000
+++ plugins/DebuggerCore/unix/netbsd/DialogMemoryAccess.ui
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp
index bafcd94ef6..8e71f3383d 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/FeatureDetect.cpp.orig 2017-02-19 00:51:04.582071788 +0000
+--- plugins/DebuggerCore/unix/netbsd/FeatureDetect.cpp.orig 2017-02-19 02:09:05.342456556 +0000
+++ plugins/DebuggerCore/unix/netbsd/FeatureDetect.cpp
@@ -0,0 +1,174 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h
index 35fdd5f1f8..0cf571360e 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_FeatureDetect.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/FeatureDetect.h.orig 2017-02-19 00:51:04.588144633 +0000
+--- plugins/DebuggerCore/unix/netbsd/FeatureDetect.h.orig 2017-02-19 02:09:05.348620261 +0000
+++ plugins/DebuggerCore/unix/netbsd/FeatureDetect.h
@@ -0,0 +1,30 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp
index a4a4cc5dcf..1b57e44cbe 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformCommon.cpp.orig 2017-02-19 00:51:04.594319579 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformCommon.cpp.orig 2017-02-19 02:09:05.354823169 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformCommon.cpp
@@ -0,0 +1,189 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h
index c4a4598b28..be830778a4 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformCommon.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformCommon.h.orig 2017-02-19 00:51:04.600408397 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformCommon.h.orig 2017-02-19 02:09:05.360983490 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformCommon.h
@@ -0,0 +1,97 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp
index 1b8ab0c420..a2d6a8750a 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.cpp
@@ -1,8 +1,8 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformEvent.cpp.orig 2017-02-19 00:51:04.606553247 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformEvent.cpp.orig 2017-02-19 02:09:05.367273282 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformEvent.cpp
-@@ -0,0 +1,258 @@
+@@ -0,0 +1,428 @@
+/*
+Copyright (C) 2006 - 2015 Evan Teran
+ evan.teran%gmail.com@localhost
@@ -23,118 +23,288 @@ $NetBSD$
+
+#include "PlatformEvent.h"
+#include "edb.h"
-+#include <cstdio>
-+#include <cstring>
-+#include <fcntl.h>
-+#include <kvm.h>
-+#include <sys/exec.h>
-+#include <sys/mman.h>
-+#include <sys/param.h>
-+#include <sys/proc.h>
-+#include <sys/ptrace.h>
-+#include <sys/signalvar.h>
-+#include <sys/sysctl.h>
-+#include <sys/types.h>
-+#include <sys/user.h>
-+#include <sys/wait.h>
-+#include <unistd.h>
-+#include <signal.h> // for the SIG* definitions
-+
-+namespace DebuggerCore {
++
++namespace DebuggerCorePlugin {
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
-+PlatformEvent::PlatformEvent() : status(0), pid(-1), tid(-1), fault_address_(0), fault_code_(0) {
++PlatformEvent::PlatformEvent() : pid_(0), tid_(0), status_(0) {
++ std::memset(&siginfo_, 0, sizeof(siginfo_t));
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
-+PlatformEvent *PlatformEvent::clone() const {
++IDebugEvent *PlatformEvent::clone() const {
+ return new PlatformEvent(*this);
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
++IDebugEvent::Message PlatformEvent::createUnexpectedSignalMessage(const QString &name, int number) {
++ return Message(
++ tr("Unexpected Signal Encountered"),
++ tr("<p>The debugged application encountered a %1 (%2).</p>").arg(name).arg(number),
++ tr("% received").arg(name)
++ );
++}
++
++//------------------------------------------------------------------------------
++// Name:
++//------------------------------------------------------------------------------
+IDebugEvent::Message PlatformEvent::error_description() const {
+ Q_ASSERT(is_error());
+
-+ auto fault_address = reinterpret_cast<edb::address_t>(fault_address_);
++ auto fault_address = edb::address_t::fromZeroExtended(siginfo_.si_addr);
+
++ std::size_t debuggeePtrSize=edb::v1::pointer_size();
++ bool fullAddressKnown=debuggeePtrSize<=sizeof(void*);
++ const auto addressString=fault_address.toPointerString(fullAddressKnown);
++
++ Message message;
+ switch(code()) {
+ case SIGSEGV:
-+ return Message(
-+ tr("Illegal Access Fault"),
-+ tr(
-+ "<p>The debugged application encountered a segmentation fault.<br />The address <strong>0x%1</strong> could not be accessed.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>").arg(edb::v1::format_pointer(fault_address))
-+ );
++ switch(siginfo_.si_code) {
++ case SEGV_MAPERR:
++ message=Message(
++ tr("Illegal Access Fault"),
++ tr("<p>The debugged application encountered a segmentation fault.<br />The address <strong>%1</strong> does not appear to be mapped.</p>").arg(addressString),
++ tr("SIGSEGV: SEGV_MAPERR: Accessed address %1 not mapped").arg(addressString)
++ );
++ break;
++ case SEGV_ACCERR:
++ message=Message(
++ tr("Illegal Access Fault"),
++ tr("<p>The debugged application encountered a segmentation fault.<br />The address <strong>%1</strong> could not be accessed.</p>").arg(addressString),
++ tr("SIGSEGV: SEGV_ACCERR: Access to address %1 not permitted").arg(addressString)
++ );
++ break;
++ default:
++ message=Message(
++ tr("Illegal Access Fault"),
++ tr("<p>The debugged application encountered a segmentation fault.<br />The instruction could not be executed.</p>"),
++ tr("SIGSEGV: Segmentation fault")
++ );
++ break;
++ }
++ break;
++
+ case SIGILL:
-+ return Message(
++ message=Message(
+ tr("Illegal Instruction Fault"),
-+ tr(
-+ "<p>The debugged application attempted to execute an illegal instruction.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application attempted to execute an illegal instruction.</p>"),
++ tr("SIGILL: Illegal instruction")
+ );
++ break;
+ case SIGFPE:
-+ switch(fault_code_) {
++ switch(siginfo_.si_code) {
+ case FPE_INTDIV:
-+ return Message(
-+ tr("Divide By Zero"),
-+ tr(
-+ "<p>The debugged application tried to divide an integer value by an integer divisor of zero.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
-+ );
++ message=Message(
++ tr("Divide By Zero"),
++ tr("<p>The debugged application tried to divide an integer value by an integer divisor of zero or encountered integer division overflow.</p>"),
++ tr("SIGFPE: FPE_INTDIV: Integer division by zero or division overflow")
++ );
++ break;
++ case FPE_FLTDIV:
++ message=Message(
++ tr("Divide By Zero"),
++ tr("<p>The debugged application tried to divide an floating-point value by a floating-point divisor of zero.</p>"),
++ tr("SIGFPE: FPE_FLTDIV: Floating-point division by zero")
++ );
++ break;
++ case FPE_FLTOVF:
++ message=Message(
++ tr("Numeric Overflow"),
++ tr("<p>The debugged application encountered a numeric overflow while performing a floating-point computation.</p>"),
++ tr("SIGFPE: FPE_FLTOVF: Numeric overflow exception")
++ );
++ break;
++ case FPE_FLTUND:
++ message=Message(
++ tr("Numeric Underflow"),
++ tr("<p>The debugged application encountered a numeric underflow while performing a floating-point computation.</p>"),
++ tr("SIGFPE: FPE_FLTUND: Numeric underflow exception")
++ );
++ break;
++ case FPE_FLTRES:
++ message=Message(
++ tr("Inexact Result"),
++ tr("<p>The debugged application encountered an inexact result of a floating-point computation it was performing.</p>"),
++ tr("SIGFPE: FPE_FLTRES: Inexact result exception")
++ );
++ break;
++ case FPE_FLTINV:
++ message=Message(
++ tr("Invalid Operation"),
++ tr("<p>The debugged application attempted to perform an invalid floating-point operation.</p>"),
++ tr("SIGFPE: FPE_FLTINV: Invalid floating-point operation")
++ );
++ break;
+ default:
-+ return Message(
++ message=Message(
+ tr("Floating Point Exception"),
-+ tr(
-+ "<p>The debugged application encountered a floating-point exception.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application encountered a floating-point exception.</p>"),
++ tr("SIGFPE: Floating-point exception")
+ );
++ break;
+ }
++ break;
+
+ case SIGABRT:
-+ return Message(
++ message=Message(
+ tr("Application Aborted"),
-+ tr(
-+ "<p>The debugged application has aborted.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application has aborted.</p>"),
++ tr("SIGABRT: Application aborted")
+ );
++ break;
+ case SIGBUS:
-+ return Message(
++ message=Message(
+ tr("Bus Error"),
-+ tr(
-+ "<p>The debugged application tried to read or write data that is misaligned.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application received a bus error. Typically, this means that it tried to read or write data that is misaligned.</p>"),
++ tr("SIGBUS: Bus error")
+ );
++ break;
+#ifdef SIGSTKFLT
+ case SIGSTKFLT:
-+ return Message(
++ message=Message(
+ tr("Stack Fault"),
-+ tr(
-+ "<p>The debugged application encountered a stack fault.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application encountered a stack fault.</p>"),
++ tr("SIGSTKFLT: Stack fault")
+ );
++ break;
+#endif
+ case SIGPIPE:
-+ return Message(
++ message=Message(
+ tr("Broken Pipe Fault"),
-+ tr(
-+ "<p>The debugged application encountered a broken pipe fault.</p>"
-+ "<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>")
++ tr("<p>The debugged application encountered a broken pipe fault.</p>"),
++ tr("SIGPIPE: Pipe broken")
+ );
++ break;
++#ifdef SIGHUP
++ case SIGHUP:
++ message=createUnexpectedSignalMessage("SIGHUP", SIGHUP);
++ break;
++#endif
++#ifdef SIGINT
++ case SIGINT:
++ message=createUnexpectedSignalMessage("SIGINT", SIGINT);
++ break;
++#endif
++#ifdef SIGQUIT
++ case SIGQUIT:
++ message=createUnexpectedSignalMessage("SIGQUIT", SIGQUIT);
++ break;
++#endif
++#ifdef SIGTRAP
++ case SIGTRAP:
++ message=createUnexpectedSignalMessage("SIGTRAP", SIGTRAP);
++ break;
++#endif
++#ifdef SIGKILL
++ case SIGKILL:
++ message=createUnexpectedSignalMessage("SIGKILL", SIGKILL);
++ break;
++#endif
++#ifdef SIGUSR1
++ case SIGUSR1:
++ message=createUnexpectedSignalMessage("SIGUSR1", SIGUSR1);
++ break;
++#endif
++#ifdef SIGUSR2
++ case SIGUSR2:
++ message=createUnexpectedSignalMessage("SIGUSR2", SIGUSR2);
++ break;
++#endif
++#ifdef SIGALRM
++ case SIGALRM:
++ message=createUnexpectedSignalMessage("SIGALRM", SIGALRM);
++ break;
++#endif
++#ifdef SIGTERM
++ case SIGTERM:
++ message=createUnexpectedSignalMessage("SIGTERM", SIGTERM);
++ break;
++#endif
++#ifdef SIGCHLD
++ case SIGCHLD:
++ message=createUnexpectedSignalMessage("SIGCHLD", SIGCHLD);
++ break;
++#endif
++#ifdef SIGCONT
++ case SIGCONT:
++ message=createUnexpectedSignalMessage("SIGCONT", SIGCONT);
++ break;
++#endif
++#ifdef SIGSTOP
++ case SIGSTOP:
++ message=createUnexpectedSignalMessage("SIGSTOP", SIGSTOP);
++ break;
++#endif
++#ifdef SIGTSTP
++ case SIGTSTP:
++ message=createUnexpectedSignalMessage("SIGTSTP", SIGTSTP);
++ break;
++#endif
++#ifdef SIGTTIN
++ case SIGTTIN:
++ message=createUnexpectedSignalMessage("SIGTTIN", SIGTTIN);
++ break;
++#endif
++#ifdef SIGTTOU
++ case SIGTTOU:
++ message=createUnexpectedSignalMessage("SIGTTOU", SIGTTOU);
++ break;
++#endif
++#ifdef SIGURG
++ case SIGURG:
++ message=createUnexpectedSignalMessage("SIGURG", SIGURG);
++ break;
++#endif
++#ifdef SIGXCPU
++ case SIGXCPU:
++ message=createUnexpectedSignalMessage("SIGXCPU", SIGXCPU);
++ break;
++#endif
++#ifdef SIGXFSZ
++ case SIGXFSZ:
++ message=createUnexpectedSignalMessage("SIGXFSZ", SIGXFSZ);
++ break;
++#endif
++#ifdef SIGVTALRM
++ case SIGVTALRM:
++ message=createUnexpectedSignalMessage("SIGVTALRM", SIGVTALRM);
++ break;
++#endif
++#ifdef SIGPROF
++ case SIGPROF:
++ message=createUnexpectedSignalMessage("SIGPROF", SIGPROF);
++ break;
++#endif
++#ifdef SIGWINCH
++ case SIGWINCH:
++ message=createUnexpectedSignalMessage("SIGWINCH", SIGWINCH);
++ break;
++#endif
++#ifdef SIGIO
++ case SIGIO:
++ message=createUnexpectedSignalMessage("SIGIO", SIGIO);
++ break;
++#endif
+ default:
+ return Message();
+ }
++
++ message.message+="<p>If you would like to pass this exception to the application press Shift+[F7/F8/F9]</p>";
++ message.statusMessage+=". Shift+Run/Step to pass signal to the program";
++ return message;
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
-+IDebugEvent::REASON PlatformEvent:: reason() const {
++IDebugEvent::REASON PlatformEvent::reason() const {
+ // this basically converts our value into a 'switchable' value for convenience
+
+ if(stopped()) {
@@ -152,7 +322,7 @@ $NetBSD$
+// Name:
+//------------------------------------------------------------------------------
+IDebugEvent::TRAP_REASON PlatformEvent::trap_reason() const {
-+ switch(fault_code_) {
++ switch(siginfo_.si_code) {
+ case TRAP_TRACE: return TRAP_STEPPING;
+ default: return TRAP_BREAKPOINT;
+ }
@@ -162,7 +332,7 @@ $NetBSD$
+// Name:
+//------------------------------------------------------------------------------
+bool PlatformEvent::exited() const {
-+ return WIFEXITED(status) != 0;
++ return WIFEXITED(status_) != 0;
+}
+
+//------------------------------------------------------------------------------
@@ -217,28 +387,28 @@ $NetBSD$
+// Name:
+//------------------------------------------------------------------------------
+bool PlatformEvent::terminated() const {
-+ return WIFSIGNALED(status) != 0;
++ return WIFSIGNALED(status_) != 0;
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
+bool PlatformEvent::stopped() const {
-+ return WIFSTOPPED(status) != 0;
++ return WIFSTOPPED(status_) != 0;
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
+edb::pid_t PlatformEvent::process() const {
-+ return pid;
++ return pid_;
+}
+
+//------------------------------------------------------------------------------
+// Name:
+//------------------------------------------------------------------------------
+edb::tid_t PlatformEvent::thread() const {
-+ return tid;
++ return tid_;
+}
+
+//------------------------------------------------------------------------------
@@ -246,15 +416,15 @@ $NetBSD$
+//------------------------------------------------------------------------------
+int PlatformEvent::code() const {
+ if(stopped()) {
-+ return WSTOPSIG(status);
++ return WSTOPSIG(status_);
+ }
+
+ if(terminated()) {
-+ return WTERMSIG(status);
++ return WTERMSIG(status_);
+ }
+
+ if(exited()) {
-+ return WEXITSTATUS(status);
++ return WEXITSTATUS(status_);
+ }
+
+ return 0;
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h
index 33ce6485b9..8b8b82b929 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformEvent.h
@@ -1,8 +1,8 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformEvent.h.orig 2017-02-19 00:51:04.612693828 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformEvent.h.orig 2017-02-19 02:09:05.373398707 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformEvent.h
-@@ -0,0 +1,61 @@
+@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2006 - 2015 Evan Teran
+ evan.teran%gmail.com@localhost
@@ -24,41 +24,50 @@ $NetBSD$
+#ifndef PLATFORM_EVENT_20121005_H_
+#define PLATFORM_EVENT_20121005_H_
+
-+#include <QCoreApplication>
+#include "IDebugEvent.h"
+
-+namespace DebuggerCore {
++#include <QCoreApplication>
++#include <signal.h> // for the SIG* definitions
++
++namespace DebuggerCorePlugin {
+
-+class PlatformEvent : IDebugEvent {
++class PlatformEvent : public IDebugEvent {
+ Q_DECLARE_TR_FUNCTIONS(PlatformEvent)
+ friend class DebuggerCore;
+
+public:
+ PlatformEvent();
+
++private:
++ PlatformEvent(const PlatformEvent &) = default;
++ PlatformEvent& operator=(const PlatformEvent &) = default;
++
+public:
-+ virtual PlatformEvent *clone() const;
++ virtual IDebugEvent *clone() const override;
+
+public:
-+ virtual Message error_description() const;
-+ virtual REASON reason() const;
-+ virtual TRAP_REASON trap_reason() const;
-+ virtual bool exited() const;
-+ virtual bool is_error() const;
-+ virtual bool is_kill() const;
-+ virtual bool is_stop() const;
-+ virtual bool is_trap() const;
-+ virtual bool terminated() const;
-+ virtual bool stopped() const;
-+ virtual edb::pid_t process() const;
-+ virtual edb::tid_t thread() const;
-+ virtual int code() const;
++ virtual Message error_description() const override;
++ virtual REASON reason() const override;
++ virtual TRAP_REASON trap_reason() const override;
++ virtual bool exited() const override;
++ virtual bool is_error() const override;
++ virtual bool is_kill() const override;
++ virtual bool is_stop() const override;
++ virtual bool is_trap() const override;
++ virtual bool stopped() const override;
++ virtual bool terminated() const override;
++ virtual edb::pid_t process() const override;
++ virtual edb::tid_t thread() const override;
++ virtual int code() const override;
++
++private:
++ static IDebugEvent::Message createUnexpectedSignalMessage(const QString &name, int number);
+
+private:
-+ ptrace_siginfo_t siginfo_;
-+ edb::pid_t pid_;
-+ edb::tid_t tid_;
-+ int status_;
++ ptrace_siginfo_t siginfo_;
++ edb::pid_t pid_;
++ edb::tid_t tid_;
++ int status_;
+};
+
+}
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp
index 78c67133b9..4ab08b24d1 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.cpp
@@ -1,8 +1,8 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformProcess.cpp.orig 2017-02-19 00:51:04.618831385 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformProcess.cpp.orig 2017-02-19 02:09:05.379589420 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformProcess.cpp
-@@ -0,0 +1,19 @@
+@@ -0,0 +1,767 @@
+/*
+Copyright (C) 2015 - 2015 Evan Teran
+ evan.teran%gmail.com@localhost
@@ -21,4 +21,752 @@ $NetBSD$
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
++#define _LARGEFILE64_SOURCE
+#include "PlatformProcess.h"
++#include "DebuggerCore.h"
++#include "PlatformCommon.h"
++#include "PlatformRegion.h"
++#include "MemoryRegions.h"
++#include "edb.h"
++#include "linker.h"
++
++#include <QByteArray>
++#include <QFile>
++#include <QFileInfo>
++#include <QTextStream>
++#include <QDateTime>
++
++#include <boost/functional/hash.hpp>
++#include <fstream>
++
++#include <sys/mman.h>
++#include <sys/ptrace.h>
++#include <sys/types.h>
++#include <unistd.h>
++#include <pwd.h>
++#include <elf.h>
++
++namespace DebuggerCorePlugin {
++namespace {
++
++// Used as size of ptrace word
++#define EDB_WORDSIZE sizeof(long)
++
++void set_ok(bool &ok, long value) {
++ ok = (value != -1) || (errno == 0);
++}
++
++QStringList split_max(const QString &str, const int &maxparts) {
++ int prev_idx = 0, idx = 0;
++ QStringList items;
++ for (const QChar &c : str) {
++ if (c == ' ') {
++ if (prev_idx < idx) {
++ if (items.size() < maxparts - 1)
++ items << str.mid(prev_idx, idx - prev_idx);
++ else {
++ items << str.right(str.size() - prev_idx);
++ break;
++ }
++ }
++ prev_idx = idx + 1;
++ }
++ ++idx;
++ }
++ if (prev_idx < str.size() && items.size() < maxparts) {
++ items << str.right(str.size() - prev_idx);
++ }
++ return items;
++}
++
++//------------------------------------------------------------------------------
++// Name: process_map_line
++// Desc: parses the data from a line of a memory map file
++//------------------------------------------------------------------------------
++IRegion::pointer process_map_line(const QString &line) {
++
++ edb::address_t start;
++ edb::address_t end;
++ edb::address_t base;
++ IRegion::permissions_t permissions;
++ QString name;
++
++ const QStringList items = split_max(line, 6);
++ if(items.size() >= 3) {
++ bool ok;
++ const QStringList bounds = items[0].split("-");
++ if(bounds.size() == 2) {
++ start = edb::address_t::fromHexString(bounds[0],&ok);
++ if(ok) {
++ end = edb::address_t::fromHexString(bounds[1],&ok);
++ if(ok) {
++ base = edb::address_t::fromHexString(items[2],&ok);
++ if(ok) {
++ const QString perms = items[1];
++ permissions = 0;
++ if(perms[0] == 'r') permissions |= PROT_READ;
++ if(perms[1] == 'w') permissions |= PROT_WRITE;
++ if(perms[2] == 'x') permissions |= PROT_EXEC;
++
++ if(items.size() >= 6) {
++ name = items[5];
++ }
++
++ return std::make_shared<PlatformRegion>(start, end, base, name, permissions);
++ }
++ }
++ }
++ }
++ }
++ return nullptr;;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++template<class Addr>
++QList<Module> loaded_modules_(const IProcess* process, const std::unique_ptr<IBinary> &binary_info_) {
++ QList<Module> ret;
++
++ if(binary_info_) {
++ edb::linux::r_debug<Addr> dynamic_info;
++ if(const edb::address_t debug_pointer = binary_info_->debug_pointer()) {
++ if(process) {
++ if(process->read_bytes(debug_pointer, &dynamic_info, sizeof(dynamic_info))) {
++ if(dynamic_info.r_map) {
++
++ auto link_address = edb::address_t::fromZeroExtended(dynamic_info.r_map);
++
++ while(link_address) {
++
++ edb::linux::link_map<Addr> map;
++ if(process->read_bytes(link_address, &map, sizeof(map))) {
++ char path[PATH_MAX];
++ if(!process->read_bytes(edb::address_t::fromZeroExtended(map.l_name), &path, sizeof(path))) {
++ path[0] = '\0';
++ }
++
++ if(map.l_addr) {
++ Module module;
++ module.name = path;
++ module.base_address = map.l_addr;
++ ret.push_back(module);
++ }
++
++ link_address = edb::address_t::fromZeroExtended(map.l_next);
++ } else {
++ break;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++
++ // fallback
++ if(ret.isEmpty()) {
++ const QList<IRegion::pointer> r = edb::v1::memory_regions().regions();
++ QSet<QString> found_modules;
++
++ for(const IRegion::pointer ®ion: r) {
++
++ // we assume that modules will be listed by absolute path
++ if(region->name().startsWith("/")) {
++ if(!found_modules.contains(region->name())) {
++ Module module;
++ module.name = region->name();
++ module.base_address = region->start();
++ found_modules.insert(region->name());
++ ret.push_back(module);
++ }
++ }
++ }
++ }
++
++ return ret;
++}
++
++}
++
++//------------------------------------------------------------------------------
++// Name: PlatformProcess
++// Desc:
++//------------------------------------------------------------------------------
++PlatformProcess::PlatformProcess(DebuggerCore *core, edb::pid_t pid) : core_(core), pid_(pid), ro_mem_file_(0), rw_mem_file_(0) {
++ if (!core_->proc_mem_read_broken_) {
++ QFile* memory_file = new QFile(QString("/proc/%1/mem").arg(pid_));
++ auto flags = QIODevice::ReadOnly | QIODevice::Unbuffered;
++ if (!core_->proc_mem_write_broken_) {
++ flags |= QIODevice::WriteOnly;
++ }
++ if (memory_file->open(flags)) {
++ ro_mem_file_ = memory_file;
++ if (!core_->proc_mem_write_broken_) {
++ rw_mem_file_ = memory_file;
++ }
++ } else {
++ delete memory_file;
++ }
++ }
++}
++
++//------------------------------------------------------------------------------
++// Name: ~PlatformProcess
++// Desc:
++//------------------------------------------------------------------------------
++PlatformProcess::~PlatformProcess() {
++ if (ro_mem_file_) {
++ delete ro_mem_file_;
++ }
++}
++
++//------------------------------------------------------------------------------
++// Name: seek_addr
++// Desc: seeks memory file to given address, taking possible negativity of the
++// address into account
++//------------------------------------------------------------------------------
++void seek_addr(QFile& file, edb::address_t address) {
++ if(address <= UINT64_MAX/2) {
++ file.seek(address);
++ } else {
++ const int fd=file.handle();
++ // Seek in two parts to avoid specifying negative offset: off64_t is a signed type
++ const off64_t halfAddressTruncated=address>>1;
++ lseek64(fd,halfAddressTruncated,SEEK_SET);
++ const off64_t secondHalfAddress=address-halfAddressTruncated;
++ lseek64(fd,secondHalfAddress,SEEK_CUR);
++ }
++}
++
++
++//------------------------------------------------------------------------------
++// Name: read_bytes
++// Desc: reads <len> bytes into <buf> starting at <address>
++// Note: returns the number of bytes read <N>
++// Note: if the read is short, only the first <N> bytes are defined
++//------------------------------------------------------------------------------
++std::size_t PlatformProcess::read_bytes(edb::address_t address, void* buf, std::size_t len) const {
++ quint64 read = 0;
++
++ Q_ASSERT(buf);
++ Q_ASSERT(core_->process_ == this);
++
++ auto ptr = reinterpret_cast<char *>(buf);
++
++ if(len != 0) {
++
++ // small reads take the fast path
++ if(len == 1) {
++
++ auto it = core_->breakpoints_.find(address);
++ if(it != core_->breakpoints_.end()) {
++ *ptr = (*it)->original_byte();
++ return 1;
++ }
++
++ if(ro_mem_file_) {
++ seek_addr(*ro_mem_file_, address);
++ read = ro_mem_file_->read(ptr, 1);
++ if (read == 1) {
++ return 1;
++ }
++ return 0;
++ } else {
++ bool ok;
++ quint8 x = read_byte_via_ptrace(address, &ok);
++ if(ok) {
++ *ptr = x;
++ return 1;
++ }
++ return 0;
++ }
++ }
++
++ if(ro_mem_file_) {
++ seek_addr(*ro_mem_file_, address);
++ read = ro_mem_file_->read(ptr, len);
++ if(read == 0 || read == quint64(-1)) {
++ return 0;
++ }
++ } else {
++ for(std::size_t index = 0; index < len; ++index) {
++
++ // read a byte, if we failed, we are done
++ bool ok;
++ const quint8 x = read_byte_via_ptrace(address + index, &ok);
++ if(!ok) {
++ break;
++ }
++
++ // store it
++ reinterpret_cast<char*>(buf)[index] = x;
++
++ ++read;
++ }
++ }
++
++ // replace any breakpoints
++ for(const IBreakpoint::pointer &bp: core_->breakpoints_) {
++ if(bp->address() >= address && bp->address() < (address + read)) {
++ // show the original bytes in the buffer..
++ ptr[bp->address() - address] = bp->original_byte();
++ }
++ }
++ }
++
++ return read;
++}
++
++//------------------------------------------------------------------------------
++// Name: write_bytes
++// Desc: writes <len> bytes from <buf> starting at <address>
++//------------------------------------------------------------------------------
++std::size_t PlatformProcess::write_bytes(edb::address_t address, const void *buf, std::size_t len) {
++ quint64 written = 0;
++
++ Q_ASSERT(buf);
++ Q_ASSERT(core_->process_ == this);
++
++ if(len != 0) {
++ if(rw_mem_file_) {
++ seek_addr(*rw_mem_file_,address);
++ written = rw_mem_file_->write(reinterpret_cast<const char *>(buf), len);
++ if(written == 0 || written == quint64(-1)) {
++ return 0;
++ }
++ }
++ else {
++ // TODO write whole words at a time using ptrace_poke.
++ for(std::size_t byteIndex=0;byteIndex<len;++byteIndex) {
++ bool ok=false;
++ write_byte_via_ptrace(address+byteIndex, *(reinterpret_cast<const char*>(buf)+byteIndex), &ok);
++ if(!ok) return written;
++ ++written;
++ }
++ }
++ }
++
++ return written;
++}
++
++//------------------------------------------------------------------------------
++// Name: read_pages
++// Desc: reads <count> pages from the process starting at <address>
++// Note: buf's size must be >= count * core_->page_size()
++// Note: address should be page aligned.
++//------------------------------------------------------------------------------
++std::size_t PlatformProcess::read_pages(edb::address_t address, void *buf, std::size_t count) const {
++ Q_ASSERT(buf);
++ Q_ASSERT(core_->process_ == this);
++ return read_bytes(address, buf, count * core_->page_size()) / core_->page_size();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QDateTime PlatformProcess::start_time() const {
++ QFileInfo info(QString("/proc/%1/stat").arg(pid_));
++ return info.created();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QList<QByteArray> PlatformProcess::arguments() const {
++ QList<QByteArray> ret;
++
++ if(pid_ != 0) {
++ const QString command_line_file(QString("/proc/%1/cmdline").arg(pid_));
++ QFile file(command_line_file);
++
++ if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
++ QTextStream in(&file);
++
++ QByteArray s;
++ QChar ch;
++
++ while(in.status() == QTextStream::Ok) {
++ in >> ch;
++ if(ch == '\0') {
++ if(!s.isEmpty()) {
++ ret << s;
++ }
++ s.clear();
++ } else {
++ s += ch;
++ }
++ }
++
++ if(!s.isEmpty()) {
++ ret << s;
++ }
++ }
++ }
++ return ret;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QString PlatformProcess::current_working_directory() const {
++ return edb::v1::symlink_target(QString("/proc/%1/cwd").arg(pid_));
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QString PlatformProcess::executable() const {
++ return edb::v1::symlink_target(QString("/proc/%1/exe").arg(pid_));
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++edb::pid_t PlatformProcess::pid() const {
++ return pid_;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++IProcess::pointer PlatformProcess::parent() const {
++
++ struct user_stat user_stat;
++ int n = get_user_stat(pid_, &user_stat);
++ if(n >= 4) {
++ return std::make_shared<PlatformProcess>(core_, user_stat.ppid);
++ }
++
++ return nullptr;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++edb::address_t PlatformProcess::code_address() const {
++ struct user_stat user_stat;
++ int n = get_user_stat(pid_, &user_stat);
++ if(n >= 26) {
++ return user_stat.startcode;
++ }
++ return 0;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++edb::address_t PlatformProcess::data_address() const {
++ struct user_stat user_stat;
++ int n = get_user_stat(pid_, &user_stat);
++ if(n >= 27) {
++ return user_stat.endcode + 1; // endcode == startdata ?
++ }
++ return 0;
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QList<IRegion::pointer> PlatformProcess::regions() const {
++ static QList<IRegion::pointer> regions;
++ static size_t totalHash = 0;
++
++ const QString map_file(QString("/proc/%1/maps").arg(pid_));
++
++ // hash the region file to see if it changed or not
++ {
++ std::ifstream mf(map_file.toStdString());
++ size_t newHash = 0;
++ std::string line;
++
++ while(std::getline(mf,line)) {
++ boost::hash_combine(newHash, line);
++ }
++
++ if(totalHash == newHash) {
++ return regions;
++ }
++
++ totalHash = newHash;
++ regions.clear();
++ }
++
++ // it changed, so let's process it
++ QFile file(map_file);
++ if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
++
++ QTextStream in(&file);
++ QString line = in.readLine();
++
++ while(!line.isNull()) {
++ if(IRegion::pointer region = process_map_line(line)) {
++ regions.push_back(region);
++ }
++ line = in.readLine();
++ }
++ }
++
++ return regions;
++}
++
++//------------------------------------------------------------------------------
++// Name: read_byte
++// Desc: the base implementation of reading a byte
++//------------------------------------------------------------------------------
++quint8 PlatformProcess::read_byte_via_ptrace(edb::address_t address, bool *ok) const {
++ // TODO(eteran): assert that we are paused
++
++ Q_ASSERT(ok);
++ Q_ASSERT(core_->process_ == this);
++
++ *ok = false;
++
++ // if this spot is unreadable, then just return 0xff, otherwise
++ // continue as normal.
++
++ // core_->page_size() - 1 will always be 0xf* because pagesizes
++ // are always 0x10*, so the masking works
++ // range of nBytesToNextPage is [1..n] where n=pagesize, and we have to adjust
++ // if nByteToNextPage < wordsize
++ const edb::address_t nBytesToNextPage = core_->page_size() - (address & (core_->page_size() - 1));
++
++ // Avoid crossing page boundary, since next page may be unreadable
++ const edb::address_t addressShift = nBytesToNextPage < EDB_WORDSIZE ? EDB_WORDSIZE - nBytesToNextPage : 0;
++ address -= addressShift;
++
++ const long value = ptrace_peek(address, ok);
++
++ if(*ok) {
++ quint8 result;
++ // We aren't interested in `value` as in number, it's just a buffer, so no endianness magic.
++ // Just have to compensate for `addressShift` when reading it.
++ std::memcpy(&result,reinterpret_cast<const char*>(&value)+addressShift,sizeof result);
++ return result;
++ }
++
++ return 0xff;
++}
++
++
++//------------------------------------------------------------------------------
++// Name: write_byte
++// Desc: writes a single byte at a given address via ptrace API.
++// Note: assumes the this will not trample any breakpoints, must be handled
++// in calling code!
++//------------------------------------------------------------------------------
++void PlatformProcess::write_byte_via_ptrace(edb::address_t address, quint8 value, bool *ok) {
++ // TODO(eteran): assert that we are paused
++
++ Q_ASSERT(ok);
++ Q_ASSERT(core_->process_ == this);
++
++ *ok = false;
++
++ // core_->page_size() - 1 will always be 0xf* because pagesizes
++ // are always 0x10*, so the masking works
++ // range of nBytesToNextPage is [1..n] where n=pagesize, and we have to adjust
++ // if nBytesToNextPage < wordsize
++ const edb::address_t nBytesToNextPage = core_->page_size() - (address & (core_->page_size() - 1));
++
++ // Avoid crossing page boundary, since next page may be inaccessible
++ const edb::address_t addressShift = nBytesToNextPage < EDB_WORDSIZE ? EDB_WORDSIZE - nBytesToNextPage : 0;
++ address -= addressShift;
++
++ long word = ptrace_peek(address, ok);
++ if(!*ok) return;
++
++ // We aren't interested in `value` as in number, it's just a buffer, so no endianness magic.
++ // Just have to compensate for `addressShift` when writing it.
++ std::memcpy(reinterpret_cast<char*>(&word)+addressShift,&value,sizeof value);
++
++ *ok = ptrace_poke(address, word);
++}
++
++//------------------------------------------------------------------------------
++// Name: ptrace_peek
++// Desc:
++// Note: this will fail on newer versions of linux if called from a
++// different thread than the one which attached to process
++//------------------------------------------------------------------------------
++long PlatformProcess::ptrace_peek(edb::address_t address, bool *ok) const {
++ Q_ASSERT(ok);
++ Q_ASSERT(core_->process_ == this);
++
++ if (EDB_IS_32_BIT && address > 0xffffffffULL) {
++ // 32 bit ptrace can't handle such long addresses
++ *ok = false;
++ return 0;
++ }
++
++ errno = 0;
++ // NOTE: on some Linux systems ptrace prototype has ellipsis instead of third and fourth arguments
++ // Thus we can't just pass address as is on IA32 systems: it'd put 64 bit integer on stack and cause UB
++ auto nativeAddress=reinterpret_cast<const void* const>(address.toUint());
++ const long v = ptrace(PTRACE_PEEKTEXT, pid_, nativeAddress, 0);
++ set_ok(*ok, v);
++ return v;
++}
++
++//------------------------------------------------------------------------------
++// Name: ptrace_poke
++// Desc:
++//------------------------------------------------------------------------------
++bool PlatformProcess::ptrace_poke(edb::address_t address, long value) {
++
++ Q_ASSERT(core_->process_ == this);
++
++ if (EDB_IS_32_BIT && address > 0xffffffffULL) {
++ // 32 bit ptrace can't handle such long addresses
++ return 0;
++ }
++
++ // NOTE: on some Linux systems ptrace prototype has ellipsis instead of third and fourth arguments
++ // Thus we can't just pass address as is on IA32 systems: it'd put 64 bit integer on stack and cause UB
++ auto nativeAddress=reinterpret_cast<const void* const>(address.toUint());
++ return ptrace(PTRACE_POKETEXT, pid_, nativeAddress, value) != -1;
++}
++
++//------------------------------------------------------------------------------
++// Name: threads
++// Desc:
++//------------------------------------------------------------------------------
++QList<IThread::pointer> PlatformProcess::threads() const {
++
++ Q_ASSERT(core_->process_ == this);
++
++ QList<IThread::pointer> threadList;
++
++ for(auto &thread : core_->threads_) {
++ threadList.push_back(thread);
++ }
++
++ return threadList;
++}
++
++//------------------------------------------------------------------------------
++// Name: current_thread
++// Desc:
++//------------------------------------------------------------------------------
++IThread::pointer PlatformProcess::current_thread() const {
++
++ Q_ASSERT(core_->process_ == this);
++
++ auto it = core_->threads_.find(core_->active_thread_);
++ if(it != core_->threads_.end()) {
++ return it.value();
++ }
++ return IThread::pointer();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++edb::uid_t PlatformProcess::uid() const {
++
++ const QFileInfo info(QString("/proc/%1").arg(pid_));
++ return info.ownerId();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QString PlatformProcess::user() const {
++ if(const struct passwd *const pwd = ::getpwuid(uid())) {
++ return pwd->pw_name;
++ }
++
++ return QString();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QString PlatformProcess::name() const {
++ struct user_stat user_stat;
++ const int n = get_user_stat(pid_, &user_stat);
++ if(n >= 2) {
++ return user_stat.comm;
++ }
++
++ return QString();
++}
++
++//------------------------------------------------------------------------------
++// Name:
++// Desc:
++//------------------------------------------------------------------------------
++QList<Module> PlatformProcess::loaded_modules() const {
++ if(edb::v1::debuggeeIs64Bit()) {
++ return loaded_modules_<Elf64_Addr>(this, core_->binary_info_);
++ } else if(edb::v1::debuggeeIs32Bit()) {
++ return loaded_modules_<Elf32_Addr>(this, core_->binary_info_);
++ } else {
++ return QList<Module>();
++ }
++}
++
++//------------------------------------------------------------------------------
++// Name: pause
++// Desc: stops *all* threads of a process
++//------------------------------------------------------------------------------
++void PlatformProcess::pause() {
++ // belive it or not, I belive that this is sufficient for all threads
++ // this is because in the debug event handler above, a SIGSTOP is sent
++ // to all threads when any event arrives, so no need to explicitly do
++ // it here. We just need any thread to stop. So we'll just target the
++ // pid_ which will send it to any one of the threads in the process.
++ ::kill(pid_, SIGSTOP);
++}
++
++//------------------------------------------------------------------------------
++// Name: resume
++// Desc: resumes ALL threads
++//------------------------------------------------------------------------------
++void PlatformProcess::resume(edb::EVENT_STATUS status) {
++ // TODO: assert that we are paused
++ Q_ASSERT(core_->process_ == this);
++
++ if(status != edb::DEBUG_STOP) {
++ if(IThread::pointer thread = current_thread()) {
++ thread->resume(status);
++
++ // resume the other threads passing the signal they originally reported had
++ for(auto &other_thread : threads()) {
++ if(core_->waited_threads_.contains(other_thread->tid())) {
++ other_thread->resume();
++ }
++ }
++ }
++ }
++}
++
++//------------------------------------------------------------------------------
++// Name: step
++// Desc: steps the currently active thread
++//------------------------------------------------------------------------------
++void PlatformProcess::step(edb::EVENT_STATUS status) {
++ // TODO: assert that we are paused
++ Q_ASSERT(core_->process_ == this);
++
++ if(status != edb::DEBUG_STOP) {
++ if(IThread::pointer thread = current_thread()) {
++ thread->step(status);
++ }
++ }
++}
++
++}
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h
index 5c5f57bb38..94c4c0bf15 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformProcess.h
@@ -1,8 +1,8 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformProcess.h.orig 2017-02-19 00:51:04.624899484 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformProcess.h.orig 2017-02-19 02:09:05.385779377 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformProcess.h
-@@ -0,0 +1,27 @@
+@@ -0,0 +1,83 @@
+/*
+Copyright (C) 2015 - 2015 Evan Teran
+ evan.teran%gmail.com@localhost
@@ -25,8 +25,64 @@ $NetBSD$
+#define PLATOFORM_PROCESS_20150517_H_
+
+#include "IProcess.h"
++#include "Status.h"
++
++#include <QFile>
++
++namespace DebuggerCorePlugin {
++
++class DebuggerCore;
+
+class PlatformProcess : public IProcess {
++ friend class PlatformThread;
++public:
++ PlatformProcess(DebuggerCore *core, edb::pid_t pid);
++ virtual ~PlatformProcess();
++
++private:
++ PlatformProcess(const PlatformProcess &) = delete;
++ PlatformProcess& operator=(const PlatformProcess &) = delete;
++
++public:
++ virtual QDateTime start_time() const;
++ virtual QList<QByteArray> arguments() const;
++ virtual QString current_working_directory() const;
++ virtual QString executable() const;
++ virtual edb::pid_t pid() const;
++ virtual IProcess::pointer parent() const;
++ virtual edb::address_t code_address() const;
++ virtual edb::address_t data_address() const;
++ virtual QList<IRegion::pointer> regions() const;
++ virtual QList<IThread::pointer> threads() const;
++ virtual IThread::pointer current_thread() const;
++ virtual edb::uid_t uid() const;
++ virtual QString user() const;
++ virtual QString name() const;
++ virtual QList<Module> loaded_modules() const;
++
++public:
++ virtual void pause();
++ virtual void resume(edb::EVENT_STATUS status);
++ virtual void step(edb::EVENT_STATUS status);
++
++public:
++ virtual std::size_t write_bytes(edb::address_t address, const void *buf, size_t len);
++ virtual std::size_t read_bytes(edb::address_t address, void *buf, size_t len) const;
++ virtual std::size_t read_pages(edb::address_t address, void *buf, size_t count) const;
++
++private:
++ bool ptrace_poke(edb::address_t address, long value);
++ long ptrace_peek(edb::address_t address, bool *ok) const;
++ quint8 read_byte_via_ptrace(edb::address_t address, bool *ok) const;
++ void write_byte_via_ptrace(edb::address_t address, quint8 value, bool *ok);
++
++private:
++ DebuggerCore* core_;
++ edb::pid_t pid_;
++ QFile* ro_mem_file_;
++ QFile* rw_mem_file_;
+};
+
++}
++
+#endif
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp
index 9284c129e2..7a2b1e08a8 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformRegion.cpp.orig 2017-02-19 00:51:04.630983695 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformRegion.cpp.orig 2017-02-19 02:10:30.313375160 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformRegion.cpp
@@ -0,0 +1,96 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h
index 55cac0300b..86f47b46a0 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformRegion.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformRegion.h.orig 2017-02-19 00:51:04.637111215 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformRegion.h.orig 2017-02-19 02:10:30.319608887 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformRegion.h
@@ -0,0 +1,67 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp
index ef6e473baf..6a38739b33 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformState.cpp.orig 2017-02-19 00:51:04.643353107 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformState.cpp.orig 2017-02-19 02:10:30.326045942 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformState.cpp
@@ -0,0 +1,392 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h
index 995f231ade..f8cebba0e9 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformState.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformState.h.orig 2017-02-19 00:51:04.649508333 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformState.h.orig 2017-02-19 02:10:30.332431989 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformState.h
@@ -0,0 +1,68 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp
index d2addd524c..438ce1037f 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.cpp
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformThread.cpp.orig 2017-02-19 00:51:04.655743013 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformThread.cpp.orig 2017-02-19 02:10:30.338910996 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformThread.cpp
@@ -0,0 +1,444 @@
+/*
diff --git a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h
index 816a81f33d..46875e6997 100644
--- a/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h
+++ b/edb-debugger-git/patches/patch-plugins_DebuggerCore_unix_netbsd_PlatformThread.h
@@ -1,6 +1,6 @@
$NetBSD$
---- plugins/DebuggerCore/unix/netbsd/PlatformThread.h.orig 2017-02-19 00:51:04.661961825 +0000
+--- plugins/DebuggerCore/unix/netbsd/PlatformThread.h.orig 2017-02-19 02:10:30.345302936 +0000
+++ plugins/DebuggerCore/unix/netbsd/PlatformThread.h
@@ -0,0 +1,89 @@
+/*
Home |
Main Index |
Thread Index |
Old Index