124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ThreadPlanCallFunction.cpp ------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanCallFunction.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C Includes
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// C++ Includes
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Other libraries and framework includes
1507f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan#include "llvm/Support/MachO.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Project includes
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/lldb-private-log.h"
18988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Breakpoint/Breakpoint.h"
19988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Breakpoint/BreakpointLocation.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Address.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Log.h"
2249ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Core/Module.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
2449ce8969d3154e1560106cfe530444c09410f217Greg Clayton#include "lldb/Symbol/ObjectFile.h"
2529756d452be39535ded2cff50d9db4df46fe6400Sean Callanan#include "lldb/Target/LanguageRuntime.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h"
28988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham#include "lldb/Target/StopInfo.h"
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Target.h"
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h"
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/ThreadPlanRunToAddress.h"
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ThreadPlanCallFunction: Plan to call a single function
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
391e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Inghambool
401e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim InghamThreadPlanCallFunction::ConstructorSetup (Thread &thread,
411e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                          ABI *& abi,
421e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                          lldb::addr_t &start_load_addr,
431e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                          lldb::addr_t &function_load_addr)
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
452bcbaf625afd8f521da03ddaa146e7ea7650ee38Jim Ingham    SetIsMasterPlan (true);
46110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham    SetOkayToDiscard (false);
47ae0f59cf7c300089bb649fbb6159299d3ea0b143Andrew Kaylor    SetPrivate (true);
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ProcessSP process_sp (thread.GetProcess());
50f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (!process_sp)
511e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return false;
52f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
531e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    abi = process_sp->GetABI().get();
5407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!abi)
561e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return false;
5707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
58f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    TargetSP target_sp (thread.CalculateTarget());
59f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
60952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
6115dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham
6207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan    SetBreakpoints();
6307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
640ddf806dd9e71637846bf0ad46e1b2df7d02cbceSean Callanan    m_function_sp = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
651e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    // If we can't read memory at the point of the process where we are planning to put our function, we're
661e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    // not going to get any further...
671e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    Error error;
681e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    process_sp->ReadUnsignedIntegerFromMemory(m_function_sp, 4, 0, error);
691e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    if (!error.Success())
701e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    {
71845970ec09b437160da1095006d74b82ef05195fJim Ingham        m_constructor_errors.Printf ("Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", m_function_sp);
721e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        if (log)
73845970ec09b437160da1095006d74b82ef05195fJim Ingham            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
741e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return false;
751e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    }
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
77f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    Module *exe_module = target_sp->GetExecutableModulePointer();
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
795beb99d65c72cd4a4f7529c4ff8cc04a1a40769dGreg Clayton    if (exe_module == NULL)
802877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham    {
81845970ec09b437160da1095006d74b82ef05195fJim Ingham        m_constructor_errors.Printf ("Can't execute code without an executable module.");
829d56ba96d520710c55874132d44a64de1257d2faJohnny Chen        if (log)
83845970ec09b437160da1095006d74b82ef05195fJim Ingham            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
841e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return false;
852877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham    }
862877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham    else
872877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham    {
885beb99d65c72cd4a4f7529c4ff8cc04a1a40769dGreg Clayton        ObjectFile *objectFile = exe_module->GetObjectFile();
892877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        if (!objectFile)
902877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        {
91845970ec09b437160da1095006d74b82ef05195fJim Ingham            m_constructor_errors.Printf ("Could not find object file for module \"%s\".",
92845970ec09b437160da1095006d74b82ef05195fJim Ingham                                         exe_module->GetFileSpec().GetFilename().AsCString());
93845970ec09b437160da1095006d74b82ef05195fJim Ingham
949d56ba96d520710c55874132d44a64de1257d2faJohnny Chen            if (log)
95845970ec09b437160da1095006d74b82ef05195fJim Ingham                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
961e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham            return false;
972877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        }
98845970ec09b437160da1095006d74b82ef05195fJim Ingham
992877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        m_start_addr = objectFile->GetEntryPointAddress();
1002877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        if (!m_start_addr.IsValid())
1012877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        {
102845970ec09b437160da1095006d74b82ef05195fJim Ingham            m_constructor_errors.Printf ("Could not find entry point address for executable module \"%s\".",
103845970ec09b437160da1095006d74b82ef05195fJim Ingham                                         exe_module->GetFileSpec().GetFilename().AsCString());
1049d56ba96d520710c55874132d44a64de1257d2faJohnny Chen            if (log)
105845970ec09b437160da1095006d74b82ef05195fJim Ingham                log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
1061e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham            return false;
1072877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham        }
1082877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham    }
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1101e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    start_load_addr = m_start_addr.GetLoadAddress (target_sp.get());
1112877594f4442cfc4d0ed2abd30af6b8027a84fc1Jim Ingham
11215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    // Checkpoint the thread state so we can restore it later.
1132f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    if (log && log->GetVerbose())
1142f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        ReportRegisterState ("About to checkpoint thread before function call.  Original register state was:");
1152f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
11615dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    if (!thread.CheckpointThreadState (m_stored_thread_state))
11715dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    {
118845970ec09b437160da1095006d74b82ef05195fJim Ingham        m_constructor_errors.Printf ("Setting up ThreadPlanCallFunction, failed to checkpoint thread state.");
11915dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham        if (log)
120845970ec09b437160da1095006d74b82ef05195fJim Ingham            log->Printf ("ThreadPlanCallFunction(%p): %s.", this, m_constructor_errors.GetData());
1211e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return false;
12215dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    }
1231e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
1241e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham
1251e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    return true;
1261e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham}
1271e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham
1281e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim InghamThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
1294f9103faba72fdfc4b4299d6d459bc820ee597b2Matt Kopec                                                const Address &function,
1301e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                                const ClangASTType &return_type,
1311e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                                addr_t arg,
1321e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                                bool stop_other_threads,
133b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                bool unwind_on_error,
134b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                bool ignore_breakpoints,
1351e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                                addr_t *this_arg,
1361e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                                addr_t *cmd_arg) :
1371e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
1381e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_valid (false),
1391e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_stop_other_threads (stop_other_threads),
1401e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_function_addr (function),
1415ebd51f464587ba848698fdf48429adc8bad9068Filipe Cabecinhas    m_function_sp (0),
1421e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_return_type (return_type),
1431e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_takedown_done (false),
144110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham    m_stop_address (LLDB_INVALID_ADDRESS),
145b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    m_unwind_on_error (unwind_on_error),
146b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    m_ignore_breakpoints (ignore_breakpoints)
1471e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham{
1481e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    lldb::addr_t start_load_addr;
1491e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    ABI *abi;
1501e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    lldb::addr_t function_load_addr;
151110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
1521e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham        return;
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    if (this_arg && cmd_arg)
15561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    {
15661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton        if (!abi->PrepareTrivialCall (thread,
15761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      m_function_sp,
1581e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                      function_load_addr,
159989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      start_load_addr,
16061d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      this_arg,
16161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      cmd_arg,
162989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      &arg))
16361d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton            return;
16461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    }
16561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    else if (this_arg)
16661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    {
16761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton        if (!abi->PrepareTrivialCall (thread,
16861d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      m_function_sp,
1691e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                      function_load_addr,
170989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      start_load_addr,
17161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      this_arg,
172989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      &arg))
17361d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton            return;
17461d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    }
17561d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    else
17661d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    {
17761d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton        if (!abi->PrepareTrivialCall (thread,
17861d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton                                      m_function_sp,
1791e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                      function_load_addr,
180989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      start_load_addr,
181989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                      &arg))
182989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton            return;
183989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    }
184989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton
185989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    ReportRegisterState ("Function call was set up.  Register state was:");
186989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton
187989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    m_valid = true;
188989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton}
189989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton
190989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton
191989816b9505219cd67ce044d655c54ac86ecf64bGreg ClaytonThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
1924f9103faba72fdfc4b4299d6d459bc820ee597b2Matt Kopec                                                const Address &function,
193016ef8886cd429f8a53bff967e601f831e409eaaJim Ingham                                                const ClangASTType &return_type,
194989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                bool stop_other_threads,
195b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                bool unwind_on_error,
196b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham                                                bool ignore_breakpoints,
197989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg1_ptr,
198989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg2_ptr,
199989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg3_ptr,
200989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg4_ptr,
201989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg5_ptr,
202989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                                addr_t *arg6_ptr) :
203989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
204989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    m_valid (false),
205989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    m_stop_other_threads (stop_other_threads),
206574c3d63822cc7fd52bf6f6a94b6882fec4c8ce9Jim Ingham    m_function_addr (function),
20776b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    m_function_sp (0),
208016ef8886cd429f8a53bff967e601f831e409eaaJim Ingham    m_return_type (return_type),
2091e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    m_takedown_done (false),
21076b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    m_stop_address (LLDB_INVALID_ADDRESS),
211b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    m_unwind_on_error (unwind_on_error),
212b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    m_ignore_breakpoints (ignore_breakpoints)
213989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton{
2141e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    lldb::addr_t start_load_addr;
2151e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    ABI *abi;
2161e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham    lldb::addr_t function_load_addr;
217110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham    if (!ConstructorSetup (thread, abi, start_load_addr, function_load_addr))
218f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        return;
219f4124deeb9532044a38c0774ced872f2709347daGreg Clayton
220989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    if (!abi->PrepareTrivialCall (thread,
2211e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                  m_function_sp,
2221e58cef33bbfd953e2c9e7dc872c4c74e0d75352Jim Ingham                                  function_load_addr,
223989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  start_load_addr,
224989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg1_ptr,
225989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg2_ptr,
226989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg3_ptr,
227989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg4_ptr,
228989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg5_ptr,
229989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton                                  arg6_ptr))
230989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    {
23161d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton            return;
23261d4f7adb6936a6d406dd5b20452d0843e538d76Greg Clayton    }
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2342f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    ReportRegisterState ("Function call was set up.  Register state was:");
2352f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
2362f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    m_valid = true;
2372f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham}
2382f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
2392f6267ff7af90c14fe08fd88bac6a63a02069033Jim InghamThreadPlanCallFunction::~ThreadPlanCallFunction ()
2402f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham{
24189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    DoTakedown(PlanSucceeded());
2422f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham}
2432f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
2442f6267ff7af90c14fe08fd88bac6a63a02069033Jim Inghamvoid
2452f6267ff7af90c14fe08fd88bac6a63a02069033Jim InghamThreadPlanCallFunction::ReportRegisterState (const char *message)
2462f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham{
247952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP | LIBLLDB_LOG_VERBOSE));
2486dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan    if (log)
2496dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan    {
250628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton        StreamString strm;
25108d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton        RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
2522f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
2532f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        log->PutCString(message);
2542f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham
255628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton        RegisterValue reg_value;
256628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton
257628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton        for (uint32_t reg_idx = 0, num_registers = reg_ctx->GetRegisterCount();
258628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton             reg_idx < num_registers;
259628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton             ++reg_idx)
2606dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan        {
261628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton            const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
262628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton            if (reg_ctx->ReadRegister(reg_info, reg_value))
263628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton            {
264628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton                reg_value.Dump(&strm, reg_info, true, false, eFormatDefault);
265628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton                strm.EOL();
266628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton            }
2676dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan        }
268628cead3b4ae3d709d10389a3ab026e808dffa9bGreg Clayton        log->PutCString(strm.GetData());
2696dff827fc7b73b0d1850a76b99f01448c4b98e50Sean Callanan    }
27014a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan}
27114a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan
27214a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callananvoid
273038fa8e30621e0e55faed3479387d811986f28b7Jim InghamThreadPlanCallFunction::DoTakedown (bool success)
27414a97ff7ccb8d40fee3c6ff136a2c602819174ddSean Callanan{
275952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
276a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham
277a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham    if (!m_valid)
278a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham    {
279a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham        //Don't call DoTakedown if we were never valid to begin with.
280a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham        if (log)
281a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham            log->Printf ("ThreadPlanCallFunction(%p): Log called on ThreadPlanCallFunction that was never valid.", this);
282a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham        return;
283a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham    }
284a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham
2852f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    if (!m_takedown_done)
28615dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    {
287038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        if (success)
2882f085c6ca2895663687dca704589478ff040b849Greg Clayton        {
289038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            ProcessSP process_sp (m_thread.GetProcess());
290038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            const ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
291038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            if (abi && m_return_type.IsValid())
292038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            {
293038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham                const bool persistent = false;
294038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham                m_return_valobj_sp = abi->GetReturnValueObject (m_thread, m_return_type, persistent);
295038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            }
2962f085c6ca2895663687dca704589478ff040b849Greg Clayton        }
2972f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        if (log)
2985f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
2992f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        m_takedown_done = true;
300ba560cc7d03c9f7d9df81e60201c5ec75cff5232Jim Ingham        m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
30104cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham        m_real_stop_info_sp = GetPrivateStopInfo ();
30276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham        m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
303038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        SetPlanComplete(success);
30415dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham        ClearBreakpoints();
3052f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        if (log && log->GetVerbose())
3062f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham            ReportRegisterState ("Restoring thread state after function call.  Restored register state:");
30778108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham
3082f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    }
3092f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    else
3102f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham    {
3112f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        if (log)
3125f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
31315dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    }
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
3176c9662e0e5840b557fcd4bd990620e106e4a18e2Jim InghamThreadPlanCallFunction::WillPop ()
3186c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham{
31989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    DoTakedown(PlanSucceeded());
3206c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham}
3216c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Ingham
3226c9662e0e5840b557fcd4bd990620e106e4a18e2Jim Inghamvoid
323989816b9505219cd67ce044d655c54ac86ecf64bGreg ClaytonThreadPlanCallFunction::GetDescription (Stream *s, DescriptionLevel level)
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
325989816b9505219cd67ce044d655c54ac86ecf64bGreg Clayton    if (level == eDescriptionLevelBrief)
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Printf("Function call thread plan");
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
331f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        TargetSP target_sp (m_thread.CalculateTarget());
3325f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::ValidatePlan (Stream *error)
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!m_valid)
340845970ec09b437160da1095006d74b82ef05195fJim Ingham    {
341845970ec09b437160da1095006d74b82ef05195fJim Ingham        if (error)
342845970ec09b437160da1095006d74b82ef05195fJim Ingham        {
343845970ec09b437160da1095006d74b82ef05195fJim Ingham            if (m_constructor_errors.GetSize() > 0)
344845970ec09b437160da1095006d74b82ef05195fJim Ingham                error->PutCString (m_constructor_errors.GetData());
345845970ec09b437160da1095006d74b82ef05195fJim Ingham            else
346845970ec09b437160da1095006d74b82ef05195fJim Ingham                error->PutCString ("Unknown error");
347845970ec09b437160da1095006d74b82ef05195fJim Ingham        }
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
349845970ec09b437160da1095006d74b82ef05195fJim Ingham    }
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham
35589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim InghamVote
35689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim InghamThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
35789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham{
35889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    if (m_takedown_done || IsPlanComplete())
35989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        return eVoteYes;
36089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    else
36189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        return ThreadPlan::ShouldReportStop(event_ptr);
36289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham}
36389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
3657c79a27b955432dfd3ad9439640f0af2eccf37b8Jim InghamThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr)
36607f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{
367952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
36804cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham    m_real_stop_info_sp = GetPrivateStopInfo ();
3692370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham
370988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
371988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    // we answer yes.
37289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
373b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    {
374b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham        SetPlanComplete();
375988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham        return true;
376b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    }
377ba8547d98b305f7eec3fa24ddbe9a633ffe2f8f2Sean Callanan
37894fb5432f10882f8917acb7849abdba7c61277acSean Callanan    // Check if the breakpoint is one of ours.
37994fb5432f10882f8917acb7849abdba7c61277acSean Callanan
380038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    StopReason stop_reason;
381038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (!m_real_stop_info_sp)
382038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        stop_reason = eStopReasonNone;
383038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    else
384038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        stop_reason = m_real_stop_info_sp->GetStopReason();
38589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    if (log)
38689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
387038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
388038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
38994fb5432f10882f8917acb7849abdba7c61277acSean Callanan        return true;
39094fb5432f10882f8917acb7849abdba7c61277acSean Callanan
39189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    // We control breakpoints separately from other "stop reasons."  So first,
39289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    // check the case where we stopped for an internal breakpoint, in that case, continue on.
39389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    // If it is not an internal breakpoint, consult m_ignore_breakpoints.
39407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
395038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham
396038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham    if (stop_reason == eStopReasonBreakpoint)
397988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    {
398f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        ProcessSP process_sp (m_thread.CalculateProcess());
3992370a97fe5bea6fa9d82f40bb34d37d3d3bda317Jim Ingham        uint64_t break_site_id = m_real_stop_info_sp->GetValue();
400f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        BreakpointSiteSP bp_site_sp;
401f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (process_sp)
402f4124deeb9532044a38c0774ced872f2709347daGreg Clayton            bp_site_sp = process_sp->GetBreakpointSiteList().FindByID(break_site_id);
403988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham        if (bp_site_sp)
404988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham        {
405988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
406988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            bool is_internal = true;
407988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            for (uint32_t i = 0; i < num_owners; i++)
408988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            {
40907f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan                Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
41089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                if (log)
41189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
41207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
41307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan                if (!bp.IsInternal())
414988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham                {
415988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham                    is_internal = false;
416988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham                    break;
417988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham                }
418988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            }
419988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham            if (is_internal)
42089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            {
42189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                if (log)
42289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
423988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham                return false;
42489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            }
425988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham        }
42689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham
427b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham        if (m_ignore_breakpoints)
428110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham        {
42989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            if (log)
43089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
43189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            m_real_stop_info_sp->OverrideShouldStop(false);
432110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham            return true;
433110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham        }
434110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham        else
43589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        {
43689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            if (log)
43789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
43889e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            m_real_stop_info_sp->OverrideShouldStop(true);
439110b55f22f8cda703c4fb6f1c2affb8ccbef215bJim Ingham            return false;
44089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        }
44189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    }
44289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    else if (!m_unwind_on_error)
44389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham    {
44489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
44589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        return false;
446988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    }
447988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    else
448988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    {
449988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham        // If the subplan is running, any crashes are attributable to us.
45078108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham        // If we want to discard the plan, then we say we explain the stop
45178108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham        // but if we are going to be discarded, let whoever is above us
45278108e67d0f6e7a63ee7b0a98b45f283dfd0c42aJim Ingham        // explain the stop.
45389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        // But don't discard the plan if the stop would restart itself (for instance if it is a
45489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        // signal that is set not to stop.  Check that here first.  We just say we explain the stop
45589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        // but aren't done and everything will continue on from there.
45689e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham
45789e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham        if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
458038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        {
45989e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            SetPlanComplete(false);
46089e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            if (m_subplan_sp)
461038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            {
46289e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                if (m_unwind_on_error)
46389e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    return true;
46489e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                else
46589e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham                    return false;
466038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            }
467038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham            else
468038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham                return false;
469038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        }
470038fa8e30621e0e55faed3479387d811986f28b7Jim Ingham        else
47189e248f04ecb87d0df4a4b96158c3fac0a3e43c7Jim Ingham            return true;
472988ddbcdc1a7f362968a1e3bfcd7fda39e7345eeJim Ingham    }
47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::ShouldStop (Event *event_ptr)
47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4787c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete.
479b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    // We need to do that here to make sure our state is correct.
4807c79a27b955432dfd3ad9439640f0af2eccf37b8Jim Ingham    DoPlanExplainsStop(event_ptr);
481b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham
482b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    if (IsPlanComplete())
48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4842f6267ff7af90c14fe08fd88bac6a63a02069033Jim Ingham        ReportRegisterState ("Function completed.  Register state was:");
48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::StopOthers ()
49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return m_stop_other_threads;
49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::SetStopOthers (bool new_value)
50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_subplan_sp)
50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ThreadPlanRunToAddress *address_plan = static_cast<ThreadPlanRunToAddress *>(m_subplan_sp.get());
50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        address_plan->SetStopOthers(new_value);
50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_stop_other_threads = new_value;
50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerStateType
511745ac7a5826fe7c392007941a4046bfb1a8dff81Jim InghamThreadPlanCallFunction::GetPlanRunState ()
51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
51324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return eStateRunning;
51424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::DidPush ()
51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
519c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan//#define SINGLE_STEP_EXPRESSIONS
520c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan
52176b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
52276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
52376b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham
52476b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    GetThread().SetStopInfoToNothing();
52576b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham
526c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan#ifndef SINGLE_STEP_EXPRESSIONS
52724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
52824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
52924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_thread.QueueThreadPlan(m_subplan_sp, false);
53015dcb7ca49b8d8f46910cf085b4c249aac5317faJim Ingham    m_subplan_sp->SetPrivate (true);
531c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan#endif
53224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
53324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::WillStop ()
53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerThreadPlanCallFunction::MischiefManaged ()
54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
543952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
544b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham
54524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (IsPlanComplete())
54624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
54724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (log)
548a8d26ebe8e66077257eba6b0e0ca85636fbd1e55Jim Ingham            log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
54924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
55024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        ThreadPlan::MischiefManaged ();
55124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return true;
55224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
55324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
55424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
55524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
55624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
55724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
55807f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
55907f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callananvoid
56007f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean CallananThreadPlanCallFunction::SetBreakpoints ()
56107f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{
562f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    ProcessSP process_sp (m_thread.CalculateProcess());
563f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    if (process_sp)
564f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    {
565f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        m_cxx_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeC_plus_plus);
566f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        m_objc_language_runtime = process_sp->GetLanguageRuntime(eLanguageTypeObjC);
56707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
568f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (m_cxx_language_runtime)
569f4124deeb9532044a38c0774ced872f2709347daGreg Clayton            m_cxx_language_runtime->SetExceptionBreakpoints();
570f4124deeb9532044a38c0774ced872f2709347daGreg Clayton        if (m_objc_language_runtime)
571f4124deeb9532044a38c0774ced872f2709347daGreg Clayton            m_objc_language_runtime->SetExceptionBreakpoints();
572f4124deeb9532044a38c0774ced872f2709347daGreg Clayton    }
57307f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan}
57407f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan
57507f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callananvoid
57607f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean CallananThreadPlanCallFunction::ClearBreakpoints ()
57707f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan{
57829756d452be39535ded2cff50d9db4df46fe6400Sean Callanan    if (m_cxx_language_runtime)
57929756d452be39535ded2cff50d9db4df46fe6400Sean Callanan        m_cxx_language_runtime->ClearExceptionBreakpoints();
58029756d452be39535ded2cff50d9db4df46fe6400Sean Callanan    if (m_objc_language_runtime)
58129756d452be39535ded2cff50d9db4df46fe6400Sean Callanan        m_objc_language_runtime->ClearExceptionBreakpoints();
58207f3d8d674350e5efc7f762f18c82c8c6f2abb10Sean Callanan}
58394fb5432f10882f8917acb7849abdba7c61277acSean Callanan
58494fb5432f10882f8917acb7849abdba7c61277acSean Callananbool
58594fb5432f10882f8917acb7849abdba7c61277acSean CallananThreadPlanCallFunction::BreakpointsExplainStop()
58694fb5432f10882f8917acb7849abdba7c61277acSean Callanan{
58704cc48eb5cff32268a822b57f87590c9dc2643f8Jim Ingham    StopInfoSP stop_info_sp = GetPrivateStopInfo ();
58894fb5432f10882f8917acb7849abdba7c61277acSean Callanan
589b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    if ((m_cxx_language_runtime &&
590b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham            m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
591b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham       ||(m_objc_language_runtime &&
592b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham            m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
593b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    {
5940086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham        Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
5950086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham        if (log)
5960086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham            log->Printf ("ThreadPlanCallFunction::BreakpointsExplainStop - Hit an exception breakpoint, setting plan complete.");
5970086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham
598b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham        SetPlanComplete(false);
5990086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham
6000086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham        // If the user has set the ObjC language breakpoint, it would normally get priority over our internal
6010086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham        // catcher breakpoint, but in this case we can't let that happen, so force the ShouldStop here.
6020086b94b7809b9fcdc77ce5bcca1e0e64bcfef76Jim Ingham        stop_info_sp->OverrideShouldStop (true);
60329756d452be39535ded2cff50d9db4df46fe6400Sean Callanan        return true;
604b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham    }
605b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham
60694fb5432f10882f8917acb7849abdba7c61277acSean Callanan    return false;
60794fb5432f10882f8917acb7849abdba7c61277acSean Callanan}
60876b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham
60976b258db0611dad2f5b5ae51721a4bc0abd580aeJim Inghambool
61076b258db0611dad2f5b5ae51721a4bc0abd580aeJim InghamThreadPlanCallFunction::RestoreThreadState()
61176b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham{
61276b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham    return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
61376b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham}
61476b258db0611dad2f5b5ae51721a4bc0abd580aeJim Ingham
615