diff options
Diffstat (limited to 'lldb/tools/debugserver/source/FunctionProfiler.cpp')
-rw-r--r-- | lldb/tools/debugserver/source/FunctionProfiler.cpp | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/lldb/tools/debugserver/source/FunctionProfiler.cpp b/lldb/tools/debugserver/source/FunctionProfiler.cpp deleted file mode 100644 index 2fa57d3a770..00000000000 --- a/lldb/tools/debugserver/source/FunctionProfiler.cpp +++ /dev/null @@ -1,288 +0,0 @@ -//===-- FunctionProfiler.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Created by Greg Clayton on 10/8/08. -// -//===----------------------------------------------------------------------===// - -#include "FunctionProfiler.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "DNB.h" - -// Project includes - -//---------------------------------------------------------------------- -// FunctionProfiler constructor -//---------------------------------------------------------------------- -FunctionProfiler::FunctionProfiler(nub_addr_t start_addr, nub_addr_t stop_addr) : - m_pid(INVALID_NUB_PROCESS), - m_start_addr(start_addr), - m_stop_addr(stop_addr), - m_start_break_id(INVALID_NUB_BREAK_ID), - m_stop_break_id(INVALID_NUB_BREAK_ID), - m_func_entered_count(0), - m_last_pc(0), - m_last_flags(0), - m_consecutive_opcode_count(0), - m_total_opcode_count(0) -{ -} - - -FunctionProfiler::~FunctionProfiler() -{ - Clear(); -} - - -void -FunctionProfiler::Clear() -{ - if (m_pid != INVALID_NUB_PROCESS) - { - if (m_start_break_id != INVALID_NUB_BREAK_ID) - DNBBreakpointClear(m_pid, m_start_break_id); - if (m_stop_break_id != INVALID_NUB_BREAK_ID) - DNBBreakpointClear(m_pid, m_stop_break_id); - } - m_start_break_id = INVALID_NUB_BREAK_ID; - m_stop_break_id = INVALID_NUB_BREAK_ID; - m_func_entered_count = 0; - m_last_pc = 0; - m_last_flags = 0; - m_consecutive_opcode_count = 0; -} - -void -FunctionProfiler::Initialize(nub_process_t pid) -{ - //printf("FunctionProfiler::%s(0x%4.4x)\n", __FUNCTION__, pid); - Clear(); - m_pid = pid; -} - -#include "DNBDataRef.h" - -void -FunctionProfiler::SetBreakpoints() -{ -#if defined (__i386__) - nub_size_t bp_opcode_size = 1; -#elif defined (__powerpc__) || defined (__ppc__) - nub_size_t bp_opcode_size = 4; -#endif - if (m_start_addr != INVALID_NUB_ADDRESS && !NUB_BREAK_ID_IS_VALID(m_start_break_id)) - { -#if defined (__arm__) - m_start_break_id = DNBBreakpointSet(m_pid, m_start_addr & 0xFFFFFFFEu, m_start_addr & 1 ? 2 : 4, false); -#else - m_start_break_id = DNBBreakpointSet(m_pid, m_start_addr, bp_opcode_size, false); -#endif - if (NUB_BREAK_ID_IS_VALID(m_start_break_id)) - DNBBreakpointSetCallback(m_pid, m_start_break_id, FunctionProfiler::BreakpointHitCallback, this); - } - if (m_stop_addr != INVALID_NUB_ADDRESS && !NUB_BREAK_ID_IS_VALID(m_stop_break_id)) - { -#if defined (__arm__) - m_stop_break_id = DNBBreakpointSet(m_pid, m_stop_addr & 0xFFFFFFFEu, m_stop_addr & 1 ? 2 : 4, false); -#else - m_stop_break_id = DNBBreakpointSet(m_pid, m_stop_addr, bp_opcode_size, false); -#endif - if (NUB_BREAK_ID_IS_VALID(m_stop_break_id)) - DNBBreakpointSetCallback(m_pid, m_stop_break_id, FunctionProfiler::BreakpointHitCallback, this); - } -} - -nub_bool_t -FunctionProfiler::BreakpointHitCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton) -{ - printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u, baton = %p)\n", __FUNCTION__, pid, tid, breakID, baton); - return ((FunctionProfiler*) baton)->BreakpointHit(pid, tid, breakID); -} - -nub_bool_t -FunctionProfiler::BreakpointHit(nub_process_t pid, nub_thread_t tid, nub_break_t breakID) -{ - printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u)\n", __FUNCTION__, pid, tid, breakID); - if (breakID == m_start_break_id) - { - m_func_entered_count++; - printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u) START breakpoint hit (%u)\n", __FUNCTION__, pid, tid, breakID, m_func_entered_count); - } - else if (breakID == m_stop_break_id) - { - if (m_func_entered_count > 0) - m_func_entered_count--; - printf("FunctionProfiler::%s(pid = %4.4x, tid = %4.4x, breakID = %u) STOP breakpoint hit (%u)\n", __FUNCTION__, pid, tid, breakID, m_func_entered_count); - } - return true; -} - -void -FunctionProfiler::ProcessStateChanged(nub_state_t state) -{ -// printf("FunctionProfiler::%s(%s)\n", __FUNCTION__, DNBStateAsString(state)); - - switch (state) - { - case eStateInvalid: - case eStateUnloaded: - case eStateAttaching: - case eStateLaunching: - break; - - case eStateDetached: - case eStateExited: - // No sense is clearing out breakpoints if our process has exited... - m_start_break_id = INVALID_NUB_BREAK_ID; - m_stop_break_id = INVALID_NUB_BREAK_ID; - printf("[0x%8.8x - 0x%8.8x) executed %u total opcodes.\n", m_total_opcode_count); - break; - - case eStateStopped: - // Keep trying find dyld each time we stop until we do - if (!NUB_BREAK_ID_IS_VALID(m_start_break_id)) - SetBreakpoints(); - - if (ShouldStepProcess()) - { - - // TODO: do logging/tracing here - nub_thread_t tid = DNBProcessGetCurrentThread(m_pid); - DNBRegisterValue reg; - m_total_opcode_count++; - - if (DNBThreadGetRegisterValueByID(m_pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, ®)) - { - const nub_addr_t pc = reg.value.uint32; - -#if defined (__i386__) - uint8_t buf[16]; - uint32_t bytes_read = DNBProcessMemoryRead(m_pid, pc, 1, buf); - if (bytes_read == 1) - printf("0x%8.8x: %2.2x\n", pc, buf[0]); - else - printf("0x%8.8x: error: can't read opcode byte.\n", pc); - -// if (bytes_read > 0) -// { -// for (uint32_t i=0; i<bytes_read; ++i) -// { -// printf(" %2.2x", buf[i]); -// } -// } -// printf("\n"); - -#elif defined (__powerpc__) || defined (__ppc__) - - uint32_t opcode = 0; - if (DNBProcessMemoryRead(m_pid, pc, 4, &opcode) == 4) - { - printf("0x%8.8x: 0x%8.8x\n", pc, opcode); - } - -#elif defined (__arm__) - #define CPSR_T (1u << 5) - // Read the CPSR into flags - if (DNBThreadGetRegisterValueByID(m_pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FLAGS, ®)) - { - const uint32_t flags = reg.value.uint32; - - const bool curr_pc_is_thumb = (flags & CPSR_T) != 0; // check the CPSR T bit - const bool last_pc_was_thumb = (m_last_flags & CPSR_T) != 0; // check the CPSR T bit - bool opcode_is_sequential = false; - - uint32_t opcode; - // Always read four bytes for the opcode - if (DNBProcessMemoryRead(m_pid, pc, 4, &opcode) == 4) - { - if (curr_pc_is_thumb) - { - // Trim off the high 16 bits if this is a 16 bit thumb instruction - if ((opcode & 0xe000) != 0xe000 || (opcode & 0x1800) == 0) - { - opcode &= 0xFFFFu; - printf("0x%8.8x: %4.4x Thumb\n", pc, opcode); - } - else - printf("0x%8.8x: %8.8x Thumb\n", pc, opcode); - } - else - printf("0x%8.8x: %8.8x ARM\n", pc, opcode); - } - - if (m_last_flags != 0 && curr_pc_is_thumb == last_pc_was_thumb) - { - if (curr_pc_is_thumb) - { - if (pc == m_last_pc + 2) - { - opcode_is_sequential = true; - } - else if (pc == m_last_pc + 4) - { - // Check for 32 bit thumb instruction... - uint16_t opcode16; - if (DNBProcessMemoryRead(m_pid, m_last_pc, 2, &opcode16) == 2) - { - if ((opcode16 & 0xe000) == 0xe000 && (opcode16 & 0x1800) != 0) - { - // Last opcode was a 32 bit thumb instruction... - opcode_is_sequential = true; - } - } - } - } - else - { - if (pc == m_last_pc + 4) - { - opcode_is_sequential = true; - } - } - } - - - if (opcode_is_sequential) - { - m_consecutive_opcode_count++; - } - else - { - if (m_consecutive_opcode_count > 0) - { - // printf(" x %u\n", m_consecutive_opcode_count); - } - m_consecutive_opcode_count = 1; - //printf("0x%8.8x: %-5s", pc, curr_pc_is_thumb ? "Thumb" : "ARM"); - //fflush(stdout); - } - m_last_flags = flags; - } -#else -#error undefined architecture -#endif - m_last_pc = pc; - } - } - break; - - case eStateRunning: - case eStateStepping: - case eStateCrashed: - case eStateSuspended: - break; - - default: - break; - } -} |