1254721Semaste//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "lldb/Target/ThreadPlan.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste#include <string.h>
16254721Semaste// C++ Includes
17254721Semaste// Other libraries and framework includes
18254721Semaste// Project includes
19254721Semaste#include "lldb/Core/ArchSpec.h"
20254721Semaste#include "lldb/Core/DataBufferHeap.h"
21254721Semaste#include "lldb/Core/Debugger.h"
22254721Semaste#include "lldb/Core/Disassembler.h"
23254721Semaste#include "lldb/Core/Log.h"
24254721Semaste#include "lldb/Core/Module.h"
25254721Semaste#include "lldb/Core/State.h"
26254721Semaste#include "lldb/Core/Value.h"
27254721Semaste#include "lldb/Symbol/TypeList.h"
28254721Semaste#include "lldb/Target/RegisterContext.h"
29254721Semaste#include "lldb/Target/Thread.h"
30254721Semaste#include "lldb/Target/Process.h"
31254721Semaste#include "lldb/Target/Target.h"
32254721Semaste
33254721Semasteusing namespace lldb;
34254721Semasteusing namespace lldb_private;
35254721Semaste
36254721Semaste#pragma mark ThreadPlanTracer
37254721Semaste
38254721SemasteThreadPlanTracer::ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp) :
39254721Semaste    m_thread (thread),
40254721Semaste    m_single_step(true),
41254721Semaste    m_enabled (false),
42254721Semaste    m_stream_sp (stream_sp)
43254721Semaste{
44254721Semaste}
45254721Semaste
46254721SemasteThreadPlanTracer::ThreadPlanTracer (Thread &thread) :
47254721Semaste    m_thread (thread),
48254721Semaste    m_single_step(true),
49254721Semaste    m_enabled (false),
50254721Semaste    m_stream_sp ()
51254721Semaste{
52254721Semaste}
53254721Semaste
54254721SemasteStream *
55254721SemasteThreadPlanTracer::GetLogStream ()
56254721Semaste{
57254721Semaste
58254721Semaste    if (m_stream_sp.get())
59254721Semaste        return m_stream_sp.get();
60254721Semaste    else
61254721Semaste    {
62254721Semaste        TargetSP target_sp (m_thread.CalculateTarget());
63254721Semaste        if (target_sp)
64254721Semaste            return &target_sp->GetDebugger().GetOutputStream();
65254721Semaste    }
66254721Semaste    return NULL;
67254721Semaste}
68254721Semaste
69254721Semastevoid
70254721SemasteThreadPlanTracer::Log()
71254721Semaste{
72254721Semaste    SymbolContext sc;
73254721Semaste    bool show_frame_index = false;
74254721Semaste    bool show_fullpaths = false;
75254721Semaste
76254721Semaste    Stream *stream = GetLogStream();
77254721Semaste    if (stream)
78254721Semaste    {
79254721Semaste        m_thread.GetStackFrameAtIndex(0)->Dump (stream, show_frame_index, show_fullpaths);
80254721Semaste        stream->Printf("\n");
81254721Semaste        stream->Flush();
82254721Semaste    }
83254721Semaste
84254721Semaste}
85254721Semaste
86254721Semastebool
87254721SemasteThreadPlanTracer::TracerExplainsStop ()
88254721Semaste{
89254721Semaste    if (m_enabled && m_single_step)
90254721Semaste    {
91254721Semaste        lldb::StopInfoSP stop_info = m_thread.GetStopInfo();
92254721Semaste        if (stop_info->GetStopReason() == eStopReasonTrace)
93254721Semaste            return true;
94254721Semaste        else
95254721Semaste            return false;
96254721Semaste    }
97254721Semaste    else
98254721Semaste        return false;
99254721Semaste}
100254721Semaste
101254721Semaste#pragma mark ThreadPlanAssemblyTracer
102254721Semaste
103254721SemasteThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp) :
104254721Semaste    ThreadPlanTracer (thread, stream_sp),
105254721Semaste    m_disassembler_sp (),
106254721Semaste    m_intptr_type (),
107254721Semaste    m_register_values ()
108254721Semaste{
109254721Semaste}
110254721Semaste
111254721SemasteThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread) :
112254721Semaste    ThreadPlanTracer (thread),
113254721Semaste    m_disassembler_sp (),
114254721Semaste    m_intptr_type (),
115254721Semaste    m_register_values ()
116254721Semaste{
117254721Semaste}
118254721Semaste
119254721SemasteDisassembler *
120254721SemasteThreadPlanAssemblyTracer::GetDisassembler ()
121254721Semaste{
122254721Semaste    if (m_disassembler_sp.get() == NULL)
123254721Semaste        m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
124254721Semaste    return m_disassembler_sp.get();
125254721Semaste}
126254721Semaste
127254721SemasteTypeFromUser
128254721SemasteThreadPlanAssemblyTracer::GetIntPointerType()
129254721Semaste{
130254721Semaste    if (!m_intptr_type.IsValid ())
131254721Semaste    {
132254721Semaste        TargetSP target_sp (m_thread.CalculateTarget());
133254721Semaste        if (target_sp)
134254721Semaste        {
135254721Semaste            Module *exe_module = target_sp->GetExecutableModulePointer();
136254721Semaste
137254721Semaste            if (exe_module)
138254721Semaste            {
139254721Semaste                m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8));
140254721Semaste            }
141254721Semaste        }
142254721Semaste    }
143254721Semaste    return m_intptr_type;
144254721Semaste}
145254721Semaste
146254721Semaste
147254721Semaste
148254721SemasteThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer()
149254721Semaste{
150254721Semaste}
151254721Semaste
152254721Semastevoid
153254721SemasteThreadPlanAssemblyTracer::TracingStarted ()
154254721Semaste{
155254721Semaste    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
156254721Semaste
157254721Semaste    if (m_register_values.size() == 0)
158254721Semaste        m_register_values.resize (reg_ctx->GetRegisterCount());
159254721Semaste}
160254721Semaste
161254721Semastevoid
162254721SemasteThreadPlanAssemblyTracer::TracingEnded ()
163254721Semaste{
164254721Semaste    m_register_values.clear();
165254721Semaste}
166254721Semaste
167254721Semastestatic void
168254721SemastePadOutTo (StreamString &stream, int target)
169254721Semaste{
170254721Semaste    stream.Flush();
171254721Semaste
172254721Semaste    int length = stream.GetString().length();
173254721Semaste
174254721Semaste    if (length + 1 < target)
175254721Semaste        stream.Printf("%*s", target - (length + 1) + 1, "");
176254721Semaste}
177254721Semaste
178254721Semastevoid
179254721SemasteThreadPlanAssemblyTracer::Log ()
180254721Semaste{
181254721Semaste    Stream *stream = GetLogStream ();
182254721Semaste
183254721Semaste    if (!stream)
184254721Semaste        return;
185254721Semaste
186254721Semaste    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
187254721Semaste
188254721Semaste    lldb::addr_t pc = reg_ctx->GetPC();
189254721Semaste    ProcessSP process_sp (m_thread.GetProcess());
190254721Semaste    Address pc_addr;
191254721Semaste    bool addr_valid = false;
192254721Semaste    uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
193254721Semaste    addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
194254721Semaste
195254721Semaste    pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
196254721Semaste    stream->PutCString (" ");
197254721Semaste
198254721Semaste    Disassembler *disassembler = GetDisassembler();
199254721Semaste    if (disassembler)
200254721Semaste    {
201254721Semaste        Error err;
202254721Semaste        process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
203254721Semaste
204254721Semaste        if (err.Success())
205254721Semaste        {
206254721Semaste            DataExtractor extractor(buffer, sizeof(buffer),
207254721Semaste                                    process_sp->GetByteOrder(),
208254721Semaste                                    process_sp->GetAddressByteSize());
209254721Semaste
210254721Semaste			bool data_from_file = false;
211254721Semaste            if (addr_valid)
212254721Semaste                disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false, data_from_file);
213254721Semaste            else
214254721Semaste                disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false, data_from_file);
215254721Semaste
216254721Semaste            InstructionList &instruction_list = disassembler->GetInstructionList();
217254721Semaste            const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
218254721Semaste
219254721Semaste            if (instruction_list.GetSize())
220254721Semaste            {
221254721Semaste                const bool show_bytes = true;
222254721Semaste                const bool show_address = true;
223254721Semaste                Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
224254721Semaste                instruction->Dump (stream,
225254721Semaste                                   max_opcode_byte_size,
226254721Semaste                                   show_address,
227254721Semaste                                   show_bytes,
228254721Semaste                                   NULL);
229254721Semaste            }
230254721Semaste        }
231254721Semaste    }
232254721Semaste
233254721Semaste    const ABI *abi = process_sp->GetABI().get();
234254721Semaste    TypeFromUser intptr_type = GetIntPointerType();
235254721Semaste
236254721Semaste    if (abi && intptr_type.IsValid())
237254721Semaste    {
238254721Semaste        ValueList value_list;
239254721Semaste        const int num_args = 1;
240254721Semaste
241254721Semaste        for (int arg_index = 0; arg_index < num_args; ++arg_index)
242254721Semaste        {
243254721Semaste            Value value;
244254721Semaste            value.SetValueType (Value::eValueTypeScalar);
245254721Semaste//            value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType());
246254721Semaste            value.SetClangType (intptr_type);
247254721Semaste            value_list.PushValue (value);
248254721Semaste        }
249254721Semaste
250254721Semaste        if (abi->GetArgumentValues (m_thread, value_list))
251254721Semaste        {
252254721Semaste            for (int arg_index = 0; arg_index < num_args; ++arg_index)
253254721Semaste            {
254254721Semaste                stream->Printf("\n\targ[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
255254721Semaste
256254721Semaste                if (arg_index + 1 < num_args)
257254721Semaste                    stream->PutCString (", ");
258254721Semaste            }
259254721Semaste        }
260254721Semaste    }
261254721Semaste
262254721Semaste
263254721Semaste    RegisterValue reg_value;
264254721Semaste    for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
265254721Semaste         reg_num < num_registers;
266254721Semaste         ++reg_num)
267254721Semaste    {
268254721Semaste        const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
269254721Semaste        if (reg_ctx->ReadRegister (reg_info, reg_value))
270254721Semaste        {
271254721Semaste            assert (reg_num < m_register_values.size());
272254721Semaste            if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
273254721Semaste                reg_value != m_register_values[reg_num])
274254721Semaste            {
275254721Semaste                if (reg_value.GetType() != RegisterValue::eTypeInvalid)
276254721Semaste                {
277254721Semaste                    stream->PutCString ("\n\t");
278254721Semaste                    reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
279254721Semaste                }
280254721Semaste            }
281254721Semaste            m_register_values[reg_num] = reg_value;
282254721Semaste        }
283254721Semaste    }
284254721Semaste    stream->EOL();
285254721Semaste    stream->Flush();
286254721Semaste}
287