blob: 07ac4708080984a5d0f30247491a82eb6c5a0bd4 [file] [log] [blame]
Jim Ingham745ac7a2010-11-11 19:26:09 +00001//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Target/ThreadPlan.h"
11
12// C Includes
Sean Callanan5b0228a2010-11-12 03:22:21 +000013#include <string.h>
Jim Ingham745ac7a2010-11-11 19:26:09 +000014// C++ Includes
15// Other libraries and framework includes
16// Project includes
Sean Callanan5b0228a2010-11-12 03:22:21 +000017#include "lldb/Core/ArchSpec.h"
18#include "lldb/Core/DataBufferHeap.h"
Jim Ingham745ac7a2010-11-11 19:26:09 +000019#include "lldb/Core/Debugger.h"
Sean Callanan5b0228a2010-11-12 03:22:21 +000020#include "lldb/Core/Disassembler.h"
Jim Ingham745ac7a2010-11-11 19:26:09 +000021#include "lldb/Core/Log.h"
22#include "lldb/Core/State.h"
Sean Callanan5b0228a2010-11-12 03:22:21 +000023#include "lldb/Core/Value.h"
24#include "lldb/Symbol/TypeList.h"
Jim Ingham745ac7a2010-11-11 19:26:09 +000025#include "lldb/Target/RegisterContext.h"
26#include "lldb/Target/Thread.h"
27#include "lldb/Target/Process.h"
28#include "lldb/Target/Target.h"
29
30using namespace lldb;
31using namespace lldb_private;
32
Sean Callanan5b0228a2010-11-12 03:22:21 +000033#pragma mark ThreadPlanTracer
34
Jim Ingham745ac7a2010-11-11 19:26:09 +000035ThreadPlanTracer::ThreadPlanTracer (Thread &thread, lldb::StreamSP &stream_sp) :
Stephen Wilsondbeb3e12011-04-11 19:41:40 +000036 m_thread (thread),
Jim Ingham745ac7a2010-11-11 19:26:09 +000037 m_single_step(true),
38 m_enabled (false),
Jim Ingham745ac7a2010-11-11 19:26:09 +000039 m_stream_sp (stream_sp)
40{
41}
42
43ThreadPlanTracer::ThreadPlanTracer (Thread &thread) :
Stephen Wilsondbeb3e12011-04-11 19:41:40 +000044 m_thread (thread),
Jim Ingham745ac7a2010-11-11 19:26:09 +000045 m_single_step(true),
46 m_enabled (false),
Jim Ingham745ac7a2010-11-11 19:26:09 +000047 m_stream_sp ()
48{
49}
50
51Stream *
52ThreadPlanTracer::GetLogStream ()
53{
54
55 if (m_stream_sp.get())
56 return m_stream_sp.get();
57 else
Greg Claytonf4124de2012-02-21 00:09:25 +000058 {
59 TargetSP target_sp (m_thread.CalculateTarget());
60 if (target_sp)
61 return &target_sp->GetDebugger().GetOutputStream();
62 }
63 return NULL;
Jim Ingham745ac7a2010-11-11 19:26:09 +000064}
65
66void
67ThreadPlanTracer::Log()
68{
69 SymbolContext sc;
70 bool show_frame_index = false;
71 bool show_fullpaths = false;
72
Caroline Tice2b5e4e62011-06-15 19:35:17 +000073 Stream *stream = GetLogStream();
74 m_thread.GetStackFrameAtIndex(0)->Dump (stream, show_frame_index, show_fullpaths);
75 stream->Printf("\n");
76 stream->Flush();
77
Jim Ingham745ac7a2010-11-11 19:26:09 +000078}
79
80bool
81ThreadPlanTracer::TracerExplainsStop ()
82{
83 if (m_enabled && m_single_step)
84 {
85 lldb::StopInfoSP stop_info = m_thread.GetStopInfo();
86 if (stop_info->GetStopReason() == eStopReasonTrace)
87 return true;
88 else
89 return false;
90 }
91 else
92 return false;
93}
Sean Callanan5b0228a2010-11-12 03:22:21 +000094
95#pragma mark ThreadPlanAssemblyTracer
96
97ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread, lldb::StreamSP &stream_sp) :
98 ThreadPlanTracer (thread, stream_sp),
Greg Claytonc51ffbf2011-08-12 21:40:01 +000099 m_disassembler_ap (),
100 m_intptr_type (),
101 m_register_values ()
Sean Callanan5b0228a2010-11-12 03:22:21 +0000102{
Jim Inghamae7862a2010-11-17 20:19:50 +0000103}
104
105ThreadPlanAssemblyTracer::ThreadPlanAssemblyTracer (Thread &thread) :
106 ThreadPlanTracer (thread),
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000107 m_disassembler_ap (),
108 m_intptr_type (),
109 m_register_values ()
Jim Inghamae7862a2010-11-17 20:19:50 +0000110{
Jim Inghamae7862a2010-11-17 20:19:50 +0000111}
112
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000113Disassembler *
114ThreadPlanAssemblyTracer::GetDisassembler ()
Jim Inghamae7862a2010-11-17 20:19:50 +0000115{
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000116 if (m_disassembler_ap.get() == NULL)
Greg Claytonf4124de2012-02-21 00:09:25 +0000117 m_disassembler_ap.reset(Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL));
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000118 return m_disassembler_ap.get();
Sean Callanan5b0228a2010-11-12 03:22:21 +0000119}
120
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000121TypeFromUser
122ThreadPlanAssemblyTracer::GetIntPointerType()
123{
124 if (!m_intptr_type.IsValid ())
125 {
Greg Claytonf4124de2012-02-21 00:09:25 +0000126 TargetSP target_sp (m_thread.CalculateTarget());
127 if (target_sp)
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000128 {
Greg Claytonf4124de2012-02-21 00:09:25 +0000129 Module *exe_module = target_sp->GetExecutableModulePointer();
130
131 if (exe_module)
132 {
133 m_intptr_type = TypeFromUser(exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, target_sp->GetArchitecture().GetAddressByteSize() * 8),
134 exe_module->GetClangASTContext().getASTContext());
135 }
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000136 }
137 }
138 return m_intptr_type;
139}
140
141
142
Sean Callanan5b0228a2010-11-12 03:22:21 +0000143ThreadPlanAssemblyTracer::~ThreadPlanAssemblyTracer()
144{
145}
146
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000147void
148ThreadPlanAssemblyTracer::TracingStarted ()
Sean Callanan5b0228a2010-11-12 03:22:21 +0000149{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000150 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
Sean Callanan5b0228a2010-11-12 03:22:21 +0000151
152 if (m_register_values.size() == 0)
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000153 m_register_values.resize (reg_ctx->GetRegisterCount());
Sean Callanan5b0228a2010-11-12 03:22:21 +0000154}
155
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000156void
157ThreadPlanAssemblyTracer::TracingEnded ()
Sean Callanan5b0228a2010-11-12 03:22:21 +0000158{
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000159 m_register_values.clear();
Sean Callanan5b0228a2010-11-12 03:22:21 +0000160}
161
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000162static void
163PadOutTo (StreamString &stream, int target)
Sean Callanan5b0228a2010-11-12 03:22:21 +0000164{
165 stream.Flush();
166
167 int length = stream.GetString().length();
168
169 if (length + 1 < target)
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000170 stream.Printf("%*s", target - (length + 1) + 1, "");
Sean Callanan5b0228a2010-11-12 03:22:21 +0000171}
172
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000173void
174ThreadPlanAssemblyTracer::Log ()
Sean Callanan5b0228a2010-11-12 03:22:21 +0000175{
176 Stream *stream = GetLogStream ();
177
178 if (!stream)
179 return;
180
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000181 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
Sean Callanan5b0228a2010-11-12 03:22:21 +0000182
183 lldb::addr_t pc = reg_ctx->GetPC();
Greg Claytonf4124de2012-02-21 00:09:25 +0000184 ProcessSP process_sp (m_thread.GetProcess());
Sean Callanan5b0228a2010-11-12 03:22:21 +0000185 Address pc_addr;
186 bool addr_valid = false;
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000187 uint8_t buffer[16] = {0}; // Must be big enough for any single instruction
Greg Claytonf4124de2012-02-21 00:09:25 +0000188 addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress (pc, pc_addr);
Sean Callanan5b0228a2010-11-12 03:22:21 +0000189
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000190 pc_addr.Dump(stream, &m_thread, Address::DumpStyleResolvedDescription, Address::DumpStyleModuleWithFileAddress);
Jim Inghamb5867672011-06-22 21:13:28 +0000191 stream->PutCString (" ");
Sean Callanan5b0228a2010-11-12 03:22:21 +0000192
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000193 Disassembler *disassembler = GetDisassembler();
194 if (disassembler)
Sean Callanan5b0228a2010-11-12 03:22:21 +0000195 {
Sean Callanan5b0228a2010-11-12 03:22:21 +0000196 Error err;
Greg Claytonf4124de2012-02-21 00:09:25 +0000197 process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
Sean Callanan5b0228a2010-11-12 03:22:21 +0000198
199 if (err.Success())
200 {
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000201 DataExtractor extractor(buffer, sizeof(buffer),
Greg Claytonf4124de2012-02-21 00:09:25 +0000202 process_sp->GetByteOrder(),
203 process_sp->GetAddressByteSize());
Sean Callanan5b0228a2010-11-12 03:22:21 +0000204
205 if (addr_valid)
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000206 disassembler->DecodeInstructions (pc_addr, extractor, 0, 1, false);
Sean Callanan5b0228a2010-11-12 03:22:21 +0000207 else
Greg Clayton3508c382012-02-24 01:59:29 +0000208 disassembler->DecodeInstructions (Address (pc), extractor, 0, 1, false);
Sean Callanan5b0228a2010-11-12 03:22:21 +0000209
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000210 InstructionList &instruction_list = disassembler->GetInstructionList();
Greg Clayton889fbd02011-03-26 19:14:58 +0000211 const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
212
Sean Callanan5b0228a2010-11-12 03:22:21 +0000213 if (instruction_list.GetSize())
214 {
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000215 const bool show_bytes = true;
216 const bool show_address = true;
Sean Callanan5b0228a2010-11-12 03:22:21 +0000217 Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000218 instruction->Dump (stream,
Greg Clayton889fbd02011-03-26 19:14:58 +0000219 max_opcode_byte_size,
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000220 show_address,
221 show_bytes,
Greg Clayton0fef9682012-05-10 02:52:23 +0000222 NULL);
Sean Callanan5b0228a2010-11-12 03:22:21 +0000223 }
224 }
Sean Callanan5b0228a2010-11-12 03:22:21 +0000225 }
226
Greg Claytonf4124de2012-02-21 00:09:25 +0000227 const ABI *abi = process_sp->GetABI().get();
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000228 TypeFromUser intptr_type = GetIntPointerType();
229
230 if (abi && intptr_type.IsValid())
Sean Callanan5b0228a2010-11-12 03:22:21 +0000231 {
232 ValueList value_list;
233 const int num_args = 1;
234
235 for (int arg_index = 0; arg_index < num_args; ++arg_index)
236 {
237 Value value;
238 value.SetValueType (Value::eValueTypeScalar);
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000239 value.SetContext (Value::eContextTypeClangType, intptr_type.GetOpaqueQualType());
Sean Callanan5b0228a2010-11-12 03:22:21 +0000240 value_list.PushValue (value);
241 }
242
Greg Claytonc51ffbf2011-08-12 21:40:01 +0000243 if (abi->GetArgumentValues (m_thread, value_list))
Sean Callanan5b0228a2010-11-12 03:22:21 +0000244 {
245 for (int arg_index = 0; arg_index < num_args; ++arg_index)
246 {
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000247 stream->Printf("\n\targ[%d]=%llx", arg_index, value_list.GetValueAtIndex(arg_index)->GetScalar().ULongLong());
Sean Callanan5b0228a2010-11-12 03:22:21 +0000248
249 if (arg_index + 1 < num_args)
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000250 stream->PutCString (", ");
Sean Callanan5b0228a2010-11-12 03:22:21 +0000251 }
252 }
253 }
254
Sean Callanan5b0228a2010-11-12 03:22:21 +0000255
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000256 RegisterValue reg_value;
257 for (uint32_t reg_num = 0, num_registers = reg_ctx->GetRegisterCount();
258 reg_num < num_registers;
259 ++reg_num)
Sean Callanan5b0228a2010-11-12 03:22:21 +0000260 {
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000261 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
262 if (reg_ctx->ReadRegister (reg_info, reg_value))
Sean Callanan5b0228a2010-11-12 03:22:21 +0000263 {
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000264 assert (reg_num < m_register_values.size());
265 if (m_register_values[reg_num].GetType() == RegisterValue::eTypeInvalid ||
266 reg_value != m_register_values[reg_num])
267 {
268 if (reg_value.GetType() != RegisterValue::eTypeInvalid)
269 {
270 stream->PutCString ("\n\t");
271 reg_value.Dump(stream, reg_info, true, false, eFormatDefault);
272 }
273 }
274 m_register_values[reg_num] = reg_value;
Sean Callanan5b0228a2010-11-12 03:22:21 +0000275 }
276 }
Greg Claytonb9e8f6e2011-05-18 01:58:14 +0000277 stream->EOL();
Caroline Tice2b5e4e62011-06-15 19:35:17 +0000278 stream->Flush();
Sean Callanan5b0228a2010-11-12 03:22:21 +0000279}