1*9b1d27b2SMichał Górnydiff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 2*9b1d27b2SMichał Górnyindex e3707365a9c3..c4a9c82f3c63 100644 3*9b1d27b2SMichał Górny--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 4*9b1d27b2SMichał Górny+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 5*9b1d27b2SMichał Górny@@ -38,6 +38,8 @@ public: 6*9b1d27b2SMichał Górny 7*9b1d27b2SMichał Górny size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 8*9b1d27b2SMichał Górny lldb_private::Status &error) override; 9*9b1d27b2SMichał Górny+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 10*9b1d27b2SMichał Górny+ size_t size, Status &error) override; 11*9b1d27b2SMichał Górny 12*9b1d27b2SMichał Górny private: 13*9b1d27b2SMichał Górny fvc_t *m_fvc; 14*9b1d27b2SMichał Górny@@ -185,6 +187,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 15*9b1d27b2SMichał Górny // iterate through a linked list of all processes 16*9b1d27b2SMichał Górny // allproc is a pointer to the first list element, p_list field 17*9b1d27b2SMichał Górny // (found at offset_p_list) specifies the next element 18*9b1d27b2SMichał Górny+ lldb::addr_t prev = 0; 19*9b1d27b2SMichał Górny for (lldb::addr_t proc = 20*9b1d27b2SMichał Górny ReadPointerFromMemory(FindSymbol("allproc"), error); 21*9b1d27b2SMichał Górny proc != 0 && proc != LLDB_INVALID_ADDRESS; 22*9b1d27b2SMichał Górny@@ -195,6 +198,8 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 23*9b1d27b2SMichał Górny char comm[fbsd_maxcomlen + 1]; 24*9b1d27b2SMichał Górny ReadCStringFromMemory(proc + offset_p_comm, comm, sizeof(comm), error); 25*9b1d27b2SMichał Górny 26*9b1d27b2SMichał Górny+ bool interesting = false; 27*9b1d27b2SMichał Górny+ 28*9b1d27b2SMichał Górny // iterate through a linked list of all process' threads 29*9b1d27b2SMichał Górny // the initial thread is found in process' p_threads, subsequent 30*9b1d27b2SMichał Górny // elements are linked via td_plist field 31*9b1d27b2SMichał Górny@@ -231,6 +236,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 32*9b1d27b2SMichał Górny // NB: dumppcb can be LLDB_INVALID_ADDRESS if reading it failed 33*9b1d27b2SMichał Górny pcb_addr = dumppcb; 34*9b1d27b2SMichał Górny thread_desc += " (crashed)"; 35*9b1d27b2SMichał Górny+ interesting = true; 36*9b1d27b2SMichał Górny } else if (oncpu != -1) { 37*9b1d27b2SMichał Górny // if we managed to read stoppcbs and pcb_size, use them to find 38*9b1d27b2SMichał Górny // the correct PCB 39*9b1d27b2SMichał Górny@@ -239,13 +245,27 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 40*9b1d27b2SMichał Górny else 41*9b1d27b2SMichał Górny pcb_addr = LLDB_INVALID_ADDRESS; 42*9b1d27b2SMichał Górny thread_desc += llvm::formatv(" (on CPU {0})", oncpu); 43*9b1d27b2SMichał Górny+ interesting = true; 44*9b1d27b2SMichał Górny } 45*9b1d27b2SMichał Górny 46*9b1d27b2SMichał Górny ThreadSP thread_sp{ 47*9b1d27b2SMichał Górny new ThreadFreeBSDKernel(*this, tid, pcb_addr, thread_desc)}; 48*9b1d27b2SMichał Górny new_thread_list.AddThread(thread_sp); 49*9b1d27b2SMichał Górny } 50*9b1d27b2SMichał Górny+ 51*9b1d27b2SMichał Górny+ if (interesting) { 52*9b1d27b2SMichał Górny+ printf("pid %d is interesting\n", pid); 53*9b1d27b2SMichał Górny+ if (prev != 0) { 54*9b1d27b2SMichał Górny+ printf("will link %d to %d\n", prev, proc); 55*9b1d27b2SMichał Górny+ if (!WritePointerToMemory(prev + offset_p_list, proc, error)) 56*9b1d27b2SMichał Górny+ assert(0 && "write failed"); 57*9b1d27b2SMichał Górny+ } 58*9b1d27b2SMichał Górny+ prev = proc; 59*9b1d27b2SMichał Górny+ } 60*9b1d27b2SMichał Górny } 61*9b1d27b2SMichał Górny+ printf("last: %d\n", prev); 62*9b1d27b2SMichał Górny+ if (!WritePointerToMemory(prev + offset_p_list, 0, error)) 63*9b1d27b2SMichał Górny+ assert(0 && "write failed"); 64*9b1d27b2SMichał Górny } else { 65*9b1d27b2SMichał Górny const uint32_t num_threads = old_thread_list.GetSize(false); 66*9b1d27b2SMichał Górny for (uint32_t i = 0; i < num_threads; ++i) 67*9b1d27b2SMichał Górny@@ -295,6 +315,18 @@ size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf, 68*9b1d27b2SMichał Górny return rd; 69*9b1d27b2SMichał Górny } 70*9b1d27b2SMichał Górny 71*9b1d27b2SMichał Górny+size_t ProcessFreeBSDKernelFVC::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 72*9b1d27b2SMichał Górny+ size_t size, Status &error) { 73*9b1d27b2SMichał Górny+ ssize_t rd = 0; 74*9b1d27b2SMichał Górny+ rd = fvc_write(m_fvc, vm_addr, buf, size); 75*9b1d27b2SMichał Górny+ printf("fvc_write(%p, %p, %d) -> %d\n", vm_addr, buf, size, rd); 76*9b1d27b2SMichał Górny+ if (rd < 0 || static_cast<size_t>(rd) != size) { 77*9b1d27b2SMichał Górny+ error.SetErrorStringWithFormat("Writing memory failed: %s", GetError()); 78*9b1d27b2SMichał Górny+ return rd > 0 ? rd : 0; 79*9b1d27b2SMichał Górny+ } 80*9b1d27b2SMichał Górny+ return rd; 81*9b1d27b2SMichał Górny+} 82*9b1d27b2SMichał Górny+ 83*9b1d27b2SMichał Górny const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); } 84*9b1d27b2SMichał Górny 85*9b1d27b2SMichał Górny #endif // LLDB_ENABLE_FBSDVMCORE 86