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