18a203bb2SWalter Erquinigo //===-- ProcessTrace.cpp --------------------------------------------------===//
28a203bb2SWalter Erquinigo //
38a203bb2SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48a203bb2SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
58a203bb2SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68a203bb2SWalter Erquinigo //
78a203bb2SWalter Erquinigo //===----------------------------------------------------------------------===//
88a203bb2SWalter Erquinigo 
98a203bb2SWalter Erquinigo #include "lldb/Target/ProcessTrace.h"
108a203bb2SWalter Erquinigo 
118a203bb2SWalter Erquinigo #include <memory>
128a203bb2SWalter Erquinigo 
138a203bb2SWalter Erquinigo #include "lldb/Core/Module.h"
148a203bb2SWalter Erquinigo #include "lldb/Core/PluginManager.h"
15cfd96f05SWalter Erquinigo #include "lldb/Core/Section.h"
16*d9398a91SDavid Spickett #include "lldb/Target/ABI.h"
17cfd96f05SWalter Erquinigo #include "lldb/Target/SectionLoadList.h"
188a203bb2SWalter Erquinigo #include "lldb/Target/Target.h"
198a203bb2SWalter Erquinigo 
208a203bb2SWalter Erquinigo using namespace lldb;
218a203bb2SWalter Erquinigo using namespace lldb_private;
228a203bb2SWalter Erquinigo 
GetPluginDescriptionStatic()235f4980f0SPavel Labath llvm::StringRef ProcessTrace::GetPluginDescriptionStatic() {
248a203bb2SWalter Erquinigo   return "Trace process plug-in.";
258a203bb2SWalter Erquinigo }
268a203bb2SWalter Erquinigo 
Terminate()278a203bb2SWalter Erquinigo void ProcessTrace::Terminate() {
288a203bb2SWalter Erquinigo   PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance);
298a203bb2SWalter Erquinigo }
308a203bb2SWalter Erquinigo 
CreateInstance(TargetSP target_sp,ListenerSP listener_sp,const FileSpec * crash_file,bool can_connect)318a203bb2SWalter Erquinigo ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
328a203bb2SWalter Erquinigo                                        ListenerSP listener_sp,
3318e4272aSMichał Górny                                        const FileSpec *crash_file,
3418e4272aSMichał Górny                                        bool can_connect) {
3518e4272aSMichał Górny   if (can_connect)
3618e4272aSMichał Górny     return nullptr;
378a203bb2SWalter Erquinigo   return std::make_shared<ProcessTrace>(target_sp, listener_sp);
388a203bb2SWalter Erquinigo }
398a203bb2SWalter Erquinigo 
CanDebug(TargetSP target_sp,bool plugin_specified_by_name)408a203bb2SWalter Erquinigo bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
418a203bb2SWalter Erquinigo   return plugin_specified_by_name;
428a203bb2SWalter Erquinigo }
438a203bb2SWalter Erquinigo 
ProcessTrace(TargetSP target_sp,ListenerSP listener_sp)448a203bb2SWalter Erquinigo ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
45fb19f11eSWalter Erquinigo     : PostMortemProcess(target_sp, listener_sp) {}
468a203bb2SWalter Erquinigo 
~ProcessTrace()478a203bb2SWalter Erquinigo ProcessTrace::~ProcessTrace() {
488a203bb2SWalter Erquinigo   Clear();
498a203bb2SWalter Erquinigo   // We need to call finalize on the process before destroying ourselves to
508a203bb2SWalter Erquinigo   // make sure all of the broadcaster cleanup goes as planned. If we destruct
518a203bb2SWalter Erquinigo   // this class, then Process::~Process() might have problems trying to fully
528a203bb2SWalter Erquinigo   // destroy the broadcaster.
538a203bb2SWalter Erquinigo   Finalize();
548a203bb2SWalter Erquinigo }
558a203bb2SWalter Erquinigo 
DidAttach(ArchSpec & process_arch)568a203bb2SWalter Erquinigo void ProcessTrace::DidAttach(ArchSpec &process_arch) {
578a203bb2SWalter Erquinigo   ListenerSP listener_sp(
588a203bb2SWalter Erquinigo       Listener::MakeListener("lldb.process_trace.did_attach_listener"));
598a203bb2SWalter Erquinigo   HijackProcessEvents(listener_sp);
608a203bb2SWalter Erquinigo 
618a203bb2SWalter Erquinigo   SetCanJIT(false);
628a203bb2SWalter Erquinigo   StartPrivateStateThread();
638a203bb2SWalter Erquinigo   SetPrivateState(eStateStopped);
648a203bb2SWalter Erquinigo 
658a203bb2SWalter Erquinigo   EventSP event_sp;
668a203bb2SWalter Erquinigo   WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp);
678a203bb2SWalter Erquinigo 
688a203bb2SWalter Erquinigo   RestoreProcessEvents();
698a203bb2SWalter Erquinigo 
708a203bb2SWalter Erquinigo   Process::DidAttach(process_arch);
718a203bb2SWalter Erquinigo }
728a203bb2SWalter Erquinigo 
DoUpdateThreadList(ThreadList & old_thread_list,ThreadList & new_thread_list)734bb62448SWalter Erquinigo bool ProcessTrace::DoUpdateThreadList(ThreadList &old_thread_list,
748a203bb2SWalter Erquinigo                                       ThreadList &new_thread_list) {
758a203bb2SWalter Erquinigo   return false;
768a203bb2SWalter Erquinigo }
778a203bb2SWalter Erquinigo 
RefreshStateAfterStop()788a203bb2SWalter Erquinigo void ProcessTrace::RefreshStateAfterStop() {}
798a203bb2SWalter Erquinigo 
DoDestroy()808a203bb2SWalter Erquinigo Status ProcessTrace::DoDestroy() { return Status(); }
818a203bb2SWalter Erquinigo 
ReadMemory(addr_t addr,void * buf,size_t size,Status & error)828a203bb2SWalter Erquinigo size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
838a203bb2SWalter Erquinigo                                 Status &error) {
84*d9398a91SDavid Spickett   if (const ABISP &abi = GetABI())
85*d9398a91SDavid Spickett     addr = abi->FixAnyAddress(addr);
86*d9398a91SDavid Spickett 
878a203bb2SWalter Erquinigo   // Don't allow the caching that lldb_private::Process::ReadMemory does since
888a203bb2SWalter Erquinigo   // we have it all cached in the trace files.
898a203bb2SWalter Erquinigo   return DoReadMemory(addr, buf, size, error);
908a203bb2SWalter Erquinigo }
918a203bb2SWalter Erquinigo 
Clear()928a203bb2SWalter Erquinigo void ProcessTrace::Clear() { m_thread_list.Clear(); }
938a203bb2SWalter Erquinigo 
Initialize()948a203bb2SWalter Erquinigo void ProcessTrace::Initialize() {
958a203bb2SWalter Erquinigo   static llvm::once_flag g_once_flag;
968a203bb2SWalter Erquinigo 
978a203bb2SWalter Erquinigo   llvm::call_once(g_once_flag, []() {
988a203bb2SWalter Erquinigo     PluginManager::RegisterPlugin(GetPluginNameStatic(),
998a203bb2SWalter Erquinigo                                   GetPluginDescriptionStatic(), CreateInstance);
1008a203bb2SWalter Erquinigo   });
1018a203bb2SWalter Erquinigo }
1028a203bb2SWalter Erquinigo 
GetArchitecture()1038a203bb2SWalter Erquinigo ArchSpec ProcessTrace::GetArchitecture() {
1048a203bb2SWalter Erquinigo   return GetTarget().GetArchitecture();
1058a203bb2SWalter Erquinigo }
1068a203bb2SWalter Erquinigo 
GetProcessInfo(ProcessInstanceInfo & info)1078a203bb2SWalter Erquinigo bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) {
1088a203bb2SWalter Erquinigo   info.Clear();
1098a203bb2SWalter Erquinigo   info.SetProcessID(GetID());
1108a203bb2SWalter Erquinigo   info.SetArchitecture(GetArchitecture());
1118a203bb2SWalter Erquinigo   ModuleSP module_sp = GetTarget().GetExecutableModule();
1128a203bb2SWalter Erquinigo   if (module_sp) {
1138a203bb2SWalter Erquinigo     const bool add_exe_file_as_first_arg = false;
1148a203bb2SWalter Erquinigo     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
1158a203bb2SWalter Erquinigo                            add_exe_file_as_first_arg);
1168a203bb2SWalter Erquinigo   }
1178a203bb2SWalter Erquinigo   return true;
1188a203bb2SWalter Erquinigo }
1198a203bb2SWalter Erquinigo 
DoReadMemory(addr_t addr,void * buf,size_t size,Status & error)1208a203bb2SWalter Erquinigo size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size,
1218a203bb2SWalter Erquinigo                                   Status &error) {
122cfd96f05SWalter Erquinigo   Address resolved_address;
123cfd96f05SWalter Erquinigo   GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address);
124cfd96f05SWalter Erquinigo 
125cfd96f05SWalter Erquinigo   return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size,
126cfd96f05SWalter Erquinigo                                              error);
1278a203bb2SWalter Erquinigo }
128