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