1f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//===-- ProcessLinux.cpp ----------------------------------------*- C++ -*-===//
2f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//
3f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//                     The LLVM Compiler Infrastructure
4f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//
5f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// This file is distributed under the University of Illinois Open Source
6f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// License. See LICENSE.TXT for details.
7f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//
8f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//===----------------------------------------------------------------------===//
9f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
10f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// C Includes
11d1fbbb4cc0f3d4c99ba0614ea99c2df533ee9a0fStephen Wilson#include <errno.h>
12d1fbbb4cc0f3d4c99ba0614ea99c2df533ee9a0fStephen Wilson
13f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// C++ Includes
14f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// Other libraries and framework includes
15f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "lldb/Core/PluginManager.h"
16ad11546f92eb28fe7dae203c5c1707fcc86bf285Peter Collingbourne#include "lldb/Core/State.h"
17f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "lldb/Host/Host.h"
18f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "lldb/Symbol/ObjectFile.h"
1992241efe8ab5c5cd8d685e86dde28807549fcaf0Stephen Wilson#include "lldb/Target/DynamicLoader.h"
20f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "lldb/Target/Target.h"
21f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
22f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "ProcessLinux.h"
237e9964783acae183c23a7ea470cedd64472eb233Johnny Chen#include "ProcessPOSIXLog.h"
24ad11546f92eb28fe7dae203c5c1707fcc86bf285Peter Collingbourne#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
25f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson#include "ProcessMonitor.h"
264349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain#include "LinuxThread.h"
27f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
28f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonusing namespace lldb;
29f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonusing namespace lldb_private;
30f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
31f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//------------------------------------------------------------------------------
32f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// Static functions.
33f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
34e5eaa30f62c697d649966c86acd4e3c52b39b355Greg ClaytonProcessSP
35f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok ThirumurthiProcessLinux::CreateInstance(Target &target, Listener &listener, const FileSpec *core_file)
36f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
37f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi    return ProcessSP(new ProcessLinux(target, listener, (FileSpec *)core_file));
38f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
39f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
40f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonvoid
41f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::Initialize()
42f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
43f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    static bool g_initialized = false;
44f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
45f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    if (!g_initialized)
46f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    {
47ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen        g_initialized = true;
48f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson        PluginManager::RegisterPlugin(GetPluginNameStatic(),
49f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson                                      GetPluginDescriptionStatic(),
50f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson                                      CreateInstance);
51ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen
52ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen        Log::Callbacks log_callbacks = {
537e9964783acae183c23a7ea470cedd64472eb233Johnny Chen            ProcessPOSIXLog::DisableLog,
547e9964783acae183c23a7ea470cedd64472eb233Johnny Chen            ProcessPOSIXLog::EnableLog,
557e9964783acae183c23a7ea470cedd64472eb233Johnny Chen            ProcessPOSIXLog::ListLogCategories
56ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen        };
57ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen
58ac51e9f762ded2a1b390945df592e0718cc75862Johnny Chen        Log::RegisterLogChannel (ProcessLinux::GetPluginNameStatic(), log_callbacks);
597e9964783acae183c23a7ea470cedd64472eb233Johnny Chen        ProcessPOSIXLog::RegisterPluginName(GetPluginNameStatic());
60f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    }
61f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
62f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
63f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//------------------------------------------------------------------------------
64f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// Constructors and destructors.
65f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
66f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok ThirumurthiProcessLinux::ProcessLinux(Target& target, Listener &listener, FileSpec *core_file)
674349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain    : ProcessPOSIX(target, listener), m_core_file(core_file), m_stopping_threads(false)
68f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
69ce65d2f8332713f396b76e414288b9543952584cGreg Clayton#if 0
70f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    // FIXME: Putting this code in the ctor and saving the byte order in a
71f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    // member variable is a hack to avoid const qual issues in GetByteOrder.
72f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    ObjectFile *obj_file = GetTarget().GetExecutableModule()->GetObjectFile();
73f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    m_byte_order = obj_file->GetByteOrder();
74ce65d2f8332713f396b76e414288b9543952584cGreg Clayton#else
75ce65d2f8332713f396b76e414288b9543952584cGreg Clayton    // XXX: Will work only for local processes.
76ce65d2f8332713f396b76e414288b9543952584cGreg Clayton    m_byte_order = lldb::endian::InlHostByteOrder();
77ce65d2f8332713f396b76e414288b9543952584cGreg Clayton#endif
78f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
79f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
80f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonvoid
817e9964783acae183c23a7ea470cedd64472eb233Johnny ChenProcessLinux::Terminate()
82f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
83f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
844349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain
850e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
867e9964783acae183c23a7ea470cedd64472eb233Johnny ChenProcessLinux::GetPluginNameStatic()
87f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
880e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    static ConstString g_name("linux");
890e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return g_name;
90f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
91f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
927e9964783acae183c23a7ea470cedd64472eb233Johnny Chenconst char *
937e9964783acae183c23a7ea470cedd64472eb233Johnny ChenProcessLinux::GetPluginDescriptionStatic()
94f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
957e9964783acae183c23a7ea470cedd64472eb233Johnny Chen    return "Process plugin for Linux";
96f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
97f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
98f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
99c8dd570dddf0b73b74db5c1ecb8f18f023f864e7Greg Claytonbool
100b8f74aa72802d82466d3beadf2bd58616d2d26a6Johnny ChenProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
101b8f74aa72802d82466d3beadf2bd58616d2d26a6Johnny Chen{
102f1fda3748c39c92d2e79aeba0715baffabd3286bMatt Kopec    new_thread_list = old_thread_list;
103c8dd570dddf0b73b74db5c1ecb8f18f023f864e7Greg Clayton    return new_thread_list.GetSize(false) > 0;
104b8f74aa72802d82466d3beadf2bd58616d2d26a6Johnny Chen}
105b8f74aa72802d82466d3beadf2bd58616d2d26a6Johnny Chen
106d1fbbb4cc0f3d4c99ba0614ea99c2df533ee9a0fStephen Wilson
107f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson//------------------------------------------------------------------------------
108f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson// ProcessInterface protocol.
109f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
1100e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Claytonlldb_private::ConstString
111f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::GetPluginName()
112f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
1130e191607adcb0ea8ebd06c278be648a7f5c0097fGreg Clayton    return GetPluginNameStatic();
114f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
115f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
116f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonuint32_t
117f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::GetPluginVersion()
118f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
119f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    return 1;
120f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
121f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
122f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilsonvoid
123f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::GetPluginCommandHelp(const char *command, Stream *strm)
124f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
125f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
126f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
127f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonError
128f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::ExecutePluginCommand(Args &command, Stream *strm)
129f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
130f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    return Error(1, eErrorTypeGeneric);
131f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
132f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson
133f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonLog *
134f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen WilsonProcessLinux::EnablePluginLogging(Stream *strm, Args &command)
135f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson{
136f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson    return NULL;
137f6f40333e91c97cc3b3ad5fb9fc0549079a96788Stephen Wilson}
1383bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1393bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor// ProcessPOSIX override
1403bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylorvoid
1413bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew KaylorProcessLinux::StopAllThreads(lldb::tid_t stop_tid)
1423bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor{
1433bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    // If a breakpoint occurs while we're stopping threads, we'll get back
1443bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    // here, but we don't want to do it again.  Only the MonitorChildProcess
1453bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    // thread calls this function, so we don't need to protect this flag.
1463bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    if (m_stopping_threads)
1473bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor      return;
1483bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    m_stopping_threads = true;
1493bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1503bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
1513bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    if (log)
1523bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        log->Printf ("ProcessLinux::%s() stopping all threads", __FUNCTION__);
1533bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1543bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    // Walk the thread list and stop the other threads.  The thread that caused
1553bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    // the stop should already be marked as stopped before we get here.
1563bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    Mutex::Locker thread_list_lock(m_thread_list.GetMutex());
1573bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1583bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    uint32_t thread_count = m_thread_list.GetSize(false);
1593bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    for (uint32_t i = 0; i < thread_count; ++i)
1603bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    {
1613bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        POSIXThread *thread = static_cast<POSIXThread*>(
1623bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor            m_thread_list.GetThreadAtIndex(i, false).get());
1633bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        assert(thread);
1643bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        lldb::tid_t tid = thread->GetID();
1653bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        if (!StateIsStoppedState(thread->GetState(), false))
1663bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor            m_monitor->StopThread(tid);
1673bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    }
1683bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1693bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    m_stopping_threads = false;
1703bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor
1713bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor    if (log)
1723bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor        log->Printf ("ProcessLinux::%s() finished", __FUNCTION__);
1733bd2ebd670677dae45010bf53084ff85da7c6a5eAndrew Kaylor}
174f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi
1754349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain// ProcessPOSIX override
1764349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael SartainPOSIXThread *
1774349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael SartainProcessLinux::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
1784349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain{
1794349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain    return new LinuxThread(process, tid);
1804349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain}
1814349bcb8ec51f3fd447b511b2ce8292a92d3c771Michael Sartain
182f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthibool
183f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok ThirumurthiProcessLinux::CanDebug(Target &target, bool plugin_specified_by_name)
184f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi{
185f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi    if (plugin_specified_by_name)
186f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi        return true;
187f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi
188f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi    /* If core file is specified then let elf-core plugin handle it */
189f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi    if (m_core_file)
190f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi        return false;
191f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi
192f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi    return ProcessPOSIX::CanDebug(target, plugin_specified_by_name);
193f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi}
194f6f52692f0f8f79860e573ef18a9ed93ef5e2668Ashok Thirumurthi
195