19b1d27b2SMichał Górnydiff --git a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 29b1d27b2SMichał Górnyindex e3707365a9c3..c4a9c82f3c63 100644 39b1d27b2SMichał Górny--- a/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 49b1d27b2SMichał Górny+++ b/lldb/source/Plugins/Process/FreeBSDKernel/ProcessFreeBSDKernel.cpp 59b1d27b2SMichał Górny@@ -38,6 +38,8 @@ public: 69b1d27b2SMichał Górny 79b1d27b2SMichał Górny size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, 89b1d27b2SMichał Górny lldb_private::Status &error) override; 99b1d27b2SMichał Górny+ size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 109b1d27b2SMichał Górny+ size_t size, Status &error) override; 119b1d27b2SMichał Górny 129b1d27b2SMichał Górny private: 139b1d27b2SMichał Górny fvc_t *m_fvc; 149b1d27b2SMichał Górny@@ -185,6 +187,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 159b1d27b2SMichał Górny // iterate through a linked list of all processes 169b1d27b2SMichał Górny // allproc is a pointer to the first list element, p_list field 179b1d27b2SMichał Górny // (found at offset_p_list) specifies the next element 189b1d27b2SMichał Górny+ lldb::addr_t prev = 0; 199b1d27b2SMichał Górny for (lldb::addr_t proc = 209b1d27b2SMichał Górny ReadPointerFromMemory(FindSymbol("allproc"), error); 219b1d27b2SMichał Górny proc != 0 && proc != LLDB_INVALID_ADDRESS; 229b1d27b2SMichał Górny@@ -195,6 +198,8 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 239b1d27b2SMichał Górny char comm[fbsd_maxcomlen + 1]; 249b1d27b2SMichał Górny ReadCStringFromMemory(proc + offset_p_comm, comm, sizeof(comm), error); 259b1d27b2SMichał Górny 269b1d27b2SMichał Górny+ bool interesting = false; 279b1d27b2SMichał Górny+ 289b1d27b2SMichał Górny // iterate through a linked list of all process' threads 299b1d27b2SMichał Górny // the initial thread is found in process' p_threads, subsequent 309b1d27b2SMichał Górny // elements are linked via td_plist field 319b1d27b2SMichał Górny@@ -231,6 +236,7 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 329b1d27b2SMichał Górny // NB: dumppcb can be LLDB_INVALID_ADDRESS if reading it failed 339b1d27b2SMichał Górny pcb_addr = dumppcb; 349b1d27b2SMichał Górny thread_desc += " (crashed)"; 359b1d27b2SMichał Górny+ interesting = true; 369b1d27b2SMichał Górny } else if (oncpu != -1) { 379b1d27b2SMichał Górny // if we managed to read stoppcbs and pcb_size, use them to find 389b1d27b2SMichał Górny // the correct PCB 399b1d27b2SMichał Górny@@ -239,13 +245,27 @@ bool ProcessFreeBSDKernel::DoUpdateThreadList(ThreadList &old_thread_list, 409b1d27b2SMichał Górny else 419b1d27b2SMichał Górny pcb_addr = LLDB_INVALID_ADDRESS; 429b1d27b2SMichał Górny thread_desc += llvm::formatv(" (on CPU {0})", oncpu); 439b1d27b2SMichał Górny+ interesting = true; 449b1d27b2SMichał Górny } 459b1d27b2SMichał Górny 469b1d27b2SMichał Górny ThreadSP thread_sp{ 479b1d27b2SMichał Górny new ThreadFreeBSDKernel(*this, tid, pcb_addr, thread_desc)}; 489b1d27b2SMichał Górny new_thread_list.AddThread(thread_sp); 499b1d27b2SMichał Górny } 509b1d27b2SMichał Górny+ 519b1d27b2SMichał Górny+ if (interesting) { 529b1d27b2SMichał Górny+ printf("pid %d is interesting\n", pid); 539b1d27b2SMichał Górny+ if (prev != 0) { 549b1d27b2SMichał Górny+ printf("will link %d to %d\n", prev, proc); 559b1d27b2SMichał Górny+ if (!WritePointerToMemory(prev + offset_p_list, proc, error)) 569b1d27b2SMichał Górny+ assert(0 && "write failed"); 579b1d27b2SMichał Górny+ } 589b1d27b2SMichał Górny+ prev = proc; 599b1d27b2SMichał Górny+ } 609b1d27b2SMichał Górny } 619b1d27b2SMichał Górny+ printf("last: %d\n", prev); 629b1d27b2SMichał Górny+ if (!WritePointerToMemory(prev + offset_p_list, 0, error)) 639b1d27b2SMichał Górny+ assert(0 && "write failed"); 649b1d27b2SMichał Górny } else { 659b1d27b2SMichał Górny const uint32_t num_threads = old_thread_list.GetSize(false); 669b1d27b2SMichał Górny for (uint32_t i = 0; i < num_threads; ++i) 679b1d27b2SMichał Górny@@ -295,6 +315,18 @@ size_t ProcessFreeBSDKernelFVC::DoReadMemory(lldb::addr_t addr, void *buf, 689b1d27b2SMichał Górny return rd; 699b1d27b2SMichał Górny } 709b1d27b2SMichał Górny 719b1d27b2SMichał Górny+size_t ProcessFreeBSDKernelFVC::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, 729b1d27b2SMichał Górny+ size_t size, Status &error) { 739b1d27b2SMichał Górny+ ssize_t rd = 0; 749b1d27b2SMichał Górny+ rd = fvc_write(m_fvc, vm_addr, buf, size); 759b1d27b2SMichał Górny+ printf("fvc_write(%p, %p, %d) -> %d\n", vm_addr, buf, size, rd); 769b1d27b2SMichał Górny+ if (rd < 0 || static_cast<size_t>(rd) != size) { 77*0642cd76SAdrian Prantl+ error = Status::FromErrorStringWithFormat("Writing memory failed: %s", GetError()); 789b1d27b2SMichał Górny+ return rd > 0 ? rd : 0; 799b1d27b2SMichał Górny+ } 809b1d27b2SMichał Górny+ return rd; 819b1d27b2SMichał Górny+} 829b1d27b2SMichał Górny+ 839b1d27b2SMichał Górny const char *ProcessFreeBSDKernelFVC::GetError() { return fvc_geterr(m_fvc); } 849b1d27b2SMichał Górny 859b1d27b2SMichał Górny #endif // LLDB_ENABLE_FBSDVMCORE 86