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