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"
15*cfd96f05SWalter Erquinigo #include "lldb/Core/Section.h"
16*cfd96f05SWalter Erquinigo #include "lldb/Target/SectionLoadList.h"
178a203bb2SWalter Erquinigo #include "lldb/Target/Target.h"
188a203bb2SWalter Erquinigo 
198a203bb2SWalter Erquinigo using namespace lldb;
208a203bb2SWalter Erquinigo using namespace lldb_private;
218a203bb2SWalter Erquinigo 
228a203bb2SWalter Erquinigo ConstString ProcessTrace::GetPluginNameStatic() {
238a203bb2SWalter Erquinigo   static ConstString g_name("trace");
248a203bb2SWalter Erquinigo   return g_name;
258a203bb2SWalter Erquinigo }
268a203bb2SWalter Erquinigo 
278a203bb2SWalter Erquinigo const char *ProcessTrace::GetPluginDescriptionStatic() {
288a203bb2SWalter Erquinigo   return "Trace process plug-in.";
298a203bb2SWalter Erquinigo }
308a203bb2SWalter Erquinigo 
318a203bb2SWalter Erquinigo void ProcessTrace::Terminate() {
328a203bb2SWalter Erquinigo   PluginManager::UnregisterPlugin(ProcessTrace::CreateInstance);
338a203bb2SWalter Erquinigo }
348a203bb2SWalter Erquinigo 
358a203bb2SWalter Erquinigo ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp,
368a203bb2SWalter Erquinigo                                        ListenerSP listener_sp,
378a203bb2SWalter Erquinigo                                        const FileSpec *crash_file) {
388a203bb2SWalter Erquinigo   return std::make_shared<ProcessTrace>(target_sp, listener_sp);
398a203bb2SWalter Erquinigo }
408a203bb2SWalter Erquinigo 
418a203bb2SWalter Erquinigo bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) {
428a203bb2SWalter Erquinigo   return plugin_specified_by_name;
438a203bb2SWalter Erquinigo }
448a203bb2SWalter Erquinigo 
458a203bb2SWalter Erquinigo ProcessTrace::ProcessTrace(TargetSP target_sp, ListenerSP listener_sp)
468a203bb2SWalter Erquinigo     : Process(target_sp, listener_sp) {}
478a203bb2SWalter Erquinigo 
488a203bb2SWalter Erquinigo ProcessTrace::~ProcessTrace() {
498a203bb2SWalter Erquinigo   Clear();
508a203bb2SWalter Erquinigo   // We need to call finalize on the process before destroying ourselves to
518a203bb2SWalter Erquinigo   // make sure all of the broadcaster cleanup goes as planned. If we destruct
528a203bb2SWalter Erquinigo   // this class, then Process::~Process() might have problems trying to fully
538a203bb2SWalter Erquinigo   // destroy the broadcaster.
548a203bb2SWalter Erquinigo   Finalize();
558a203bb2SWalter Erquinigo }
568a203bb2SWalter Erquinigo 
578a203bb2SWalter Erquinigo ConstString ProcessTrace::GetPluginName() { return GetPluginNameStatic(); }
588a203bb2SWalter Erquinigo 
598a203bb2SWalter Erquinigo uint32_t ProcessTrace::GetPluginVersion() { return 1; }
608a203bb2SWalter Erquinigo 
618a203bb2SWalter Erquinigo void ProcessTrace::DidAttach(ArchSpec &process_arch) {
628a203bb2SWalter Erquinigo   ListenerSP listener_sp(
638a203bb2SWalter Erquinigo       Listener::MakeListener("lldb.process_trace.did_attach_listener"));
648a203bb2SWalter Erquinigo   HijackProcessEvents(listener_sp);
658a203bb2SWalter Erquinigo 
668a203bb2SWalter Erquinigo   SetCanJIT(false);
678a203bb2SWalter Erquinigo   StartPrivateStateThread();
688a203bb2SWalter Erquinigo   SetPrivateState(eStateStopped);
698a203bb2SWalter Erquinigo 
708a203bb2SWalter Erquinigo   EventSP event_sp;
718a203bb2SWalter Erquinigo   WaitForProcessToStop(llvm::None, &event_sp, true, listener_sp);
728a203bb2SWalter Erquinigo 
738a203bb2SWalter Erquinigo   RestoreProcessEvents();
748a203bb2SWalter Erquinigo 
758a203bb2SWalter Erquinigo   Process::DidAttach(process_arch);
768a203bb2SWalter Erquinigo }
778a203bb2SWalter Erquinigo 
788a203bb2SWalter Erquinigo bool ProcessTrace::UpdateThreadList(ThreadList &old_thread_list,
798a203bb2SWalter Erquinigo                                     ThreadList &new_thread_list) {
808a203bb2SWalter Erquinigo   return false;
818a203bb2SWalter Erquinigo }
828a203bb2SWalter Erquinigo 
838a203bb2SWalter Erquinigo void ProcessTrace::RefreshStateAfterStop() {}
848a203bb2SWalter Erquinigo 
858a203bb2SWalter Erquinigo Status ProcessTrace::DoDestroy() { return Status(); }
868a203bb2SWalter Erquinigo 
878a203bb2SWalter Erquinigo bool ProcessTrace::IsAlive() { return true; }
888a203bb2SWalter Erquinigo 
898a203bb2SWalter Erquinigo size_t ProcessTrace::ReadMemory(addr_t addr, void *buf, size_t size,
908a203bb2SWalter Erquinigo                                 Status &error) {
918a203bb2SWalter Erquinigo   // Don't allow the caching that lldb_private::Process::ReadMemory does since
928a203bb2SWalter Erquinigo   // we have it all cached in the trace files.
938a203bb2SWalter Erquinigo   return DoReadMemory(addr, buf, size, error);
948a203bb2SWalter Erquinigo }
958a203bb2SWalter Erquinigo 
968a203bb2SWalter Erquinigo void ProcessTrace::Clear() { m_thread_list.Clear(); }
978a203bb2SWalter Erquinigo 
988a203bb2SWalter Erquinigo void ProcessTrace::Initialize() {
998a203bb2SWalter Erquinigo   static llvm::once_flag g_once_flag;
1008a203bb2SWalter Erquinigo 
1018a203bb2SWalter Erquinigo   llvm::call_once(g_once_flag, []() {
1028a203bb2SWalter Erquinigo     PluginManager::RegisterPlugin(GetPluginNameStatic(),
1038a203bb2SWalter Erquinigo                                   GetPluginDescriptionStatic(), CreateInstance);
1048a203bb2SWalter Erquinigo   });
1058a203bb2SWalter Erquinigo }
1068a203bb2SWalter Erquinigo 
1078a203bb2SWalter Erquinigo ArchSpec ProcessTrace::GetArchitecture() {
1088a203bb2SWalter Erquinigo   return GetTarget().GetArchitecture();
1098a203bb2SWalter Erquinigo }
1108a203bb2SWalter Erquinigo 
1118a203bb2SWalter Erquinigo bool ProcessTrace::GetProcessInfo(ProcessInstanceInfo &info) {
1128a203bb2SWalter Erquinigo   info.Clear();
1138a203bb2SWalter Erquinigo   info.SetProcessID(GetID());
1148a203bb2SWalter Erquinigo   info.SetArchitecture(GetArchitecture());
1158a203bb2SWalter Erquinigo   ModuleSP module_sp = GetTarget().GetExecutableModule();
1168a203bb2SWalter Erquinigo   if (module_sp) {
1178a203bb2SWalter Erquinigo     const bool add_exe_file_as_first_arg = false;
1188a203bb2SWalter Erquinigo     info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(),
1198a203bb2SWalter Erquinigo                            add_exe_file_as_first_arg);
1208a203bb2SWalter Erquinigo   }
1218a203bb2SWalter Erquinigo   return true;
1228a203bb2SWalter Erquinigo }
1238a203bb2SWalter Erquinigo 
1248a203bb2SWalter Erquinigo size_t ProcessTrace::DoReadMemory(addr_t addr, void *buf, size_t size,
1258a203bb2SWalter Erquinigo                                   Status &error) {
126*cfd96f05SWalter Erquinigo   Address resolved_address;
127*cfd96f05SWalter Erquinigo   GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, resolved_address);
128*cfd96f05SWalter Erquinigo 
129*cfd96f05SWalter Erquinigo   return GetTarget().ReadMemoryFromFileCache(resolved_address, buf, size,
130*cfd96f05SWalter Erquinigo                                              error);
1318a203bb2SWalter Erquinigo }
132