Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,206 @@
//===-- ARM_DWARF_Registers.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef ARM_DWARF_Registers_h_
#define ARM_DWARF_Registers_h_
enum {
dwarf_r0 = 0,
dwarf_r1,
dwarf_r2,
dwarf_r3,
dwarf_r4,
dwarf_r5,
dwarf_r6,
dwarf_r7,
dwarf_r8,
dwarf_r9,
dwarf_r10,
dwarf_r11,
dwarf_r12,
dwarf_sp,
dwarf_lr,
dwarf_pc,
dwarf_cpsr,
dwarf_s0 = 64,
dwarf_s1,
dwarf_s2,
dwarf_s3,
dwarf_s4,
dwarf_s5,
dwarf_s6,
dwarf_s7,
dwarf_s8,
dwarf_s9,
dwarf_s10,
dwarf_s11,
dwarf_s12,
dwarf_s13,
dwarf_s14,
dwarf_s15,
dwarf_s16,
dwarf_s17,
dwarf_s18,
dwarf_s19,
dwarf_s20,
dwarf_s21,
dwarf_s22,
dwarf_s23,
dwarf_s24,
dwarf_s25,
dwarf_s26,
dwarf_s27,
dwarf_s28,
dwarf_s29,
dwarf_s30,
dwarf_s31,
// FPA Registers 0-7
dwarf_f0 = 96,
dwarf_f1,
dwarf_f2,
dwarf_f3,
dwarf_f4,
dwarf_f5,
dwarf_f6,
dwarf_f7,
// Intel wireless MMX general purpose registers 0 - 7
dwarf_wCGR0 = 104,
dwarf_wCGR1,
dwarf_wCGR2,
dwarf_wCGR3,
dwarf_wCGR4,
dwarf_wCGR5,
dwarf_wCGR6,
dwarf_wCGR7,
// XScale accumulator register 07 (they do overlap with wCGR0 - wCGR7)
dwarf_ACC0 = 104,
dwarf_ACC1,
dwarf_ACC2,
dwarf_ACC3,
dwarf_ACC4,
dwarf_ACC5,
dwarf_ACC6,
dwarf_ACC7,
// Intel wireless MMX data registers 0 - 15
dwarf_wR0 = 112,
dwarf_wR1,
dwarf_wR2,
dwarf_wR3,
dwarf_wR4,
dwarf_wR5,
dwarf_wR6,
dwarf_wR7,
dwarf_wR8,
dwarf_wR9,
dwarf_wR10,
dwarf_wR11,
dwarf_wR12,
dwarf_wR13,
dwarf_wR14,
dwarf_wR15,
dwarf_spsr = 128,
dwarf_spsr_fiq,
dwarf_spsr_irq,
dwarf_spsr_abt,
dwarf_spsr_und,
dwarf_spsr_svc,
dwarf_r8_usr = 144,
dwarf_r9_usr,
dwarf_r10_usr,
dwarf_r11_usr,
dwarf_r12_usr,
dwarf_r13_usr,
dwarf_r14_usr,
dwarf_r8_fiq,
dwarf_r9_fiq,
dwarf_r10_fiq,
dwarf_r11_fiq,
dwarf_r12_fiq,
dwarf_r13_fiq,
dwarf_r14_fiq,
dwarf_r13_irq,
dwarf_r14_irq,
dwarf_r13_abt,
dwarf_r14_abt,
dwarf_r13_und,
dwarf_r14_und,
dwarf_r13_svc,
dwarf_r14_svc,
// Intel wireless MMX control register in co-processor 0 - 7
dwarf_wC0 = 192,
dwarf_wC1,
dwarf_wC2,
dwarf_wC3,
dwarf_wC4,
dwarf_wC5,
dwarf_wC6,
dwarf_wC7,
// VFP-v3/Neon
dwarf_d0 = 256,
dwarf_d1,
dwarf_d2,
dwarf_d3,
dwarf_d4,
dwarf_d5,
dwarf_d6,
dwarf_d7,
dwarf_d8,
dwarf_d9,
dwarf_d10,
dwarf_d11,
dwarf_d12,
dwarf_d13,
dwarf_d14,
dwarf_d15,
dwarf_d16,
dwarf_d17,
dwarf_d18,
dwarf_d19,
dwarf_d20,
dwarf_d21,
dwarf_d22,
dwarf_d23,
dwarf_d24,
dwarf_d25,
dwarf_d26,
dwarf_d27,
dwarf_d28,
dwarf_d29,
dwarf_d30,
dwarf_d31,
// Neon quadword registers
dwarf_q0 = 288,
dwarf_q1,
dwarf_q2,
dwarf_q3,
dwarf_q4,
dwarf_q5,
dwarf_q6,
dwarf_q7,
dwarf_q8,
dwarf_q9,
dwarf_q10,
dwarf_q11,
dwarf_q12,
dwarf_q13,
dwarf_q14,
dwarf_q15
};
#endif // ARM_DWARF_Registers_h_

View File

@@ -0,0 +1,34 @@
//===-- ARM_ehframe_Registers.h -------------------------------------*- C++
//-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef utility_ARM_ehframe_Registers_h_
#define utility_ARM_ehframe_Registers_h_
enum {
ehframe_r0 = 0,
ehframe_r1,
ehframe_r2,
ehframe_r3,
ehframe_r4,
ehframe_r5,
ehframe_r6,
ehframe_r7,
ehframe_r8,
ehframe_r9,
ehframe_r10,
ehframe_r11,
ehframe_r12,
ehframe_sp,
ehframe_lr,
ehframe_pc,
ehframe_cpsr
};
#endif // utility_ARM_ehframe_Registers_h_

View File

@@ -0,0 +1,229 @@
include(CheckCXXCompilerFlag)
include(CheckLibraryExists)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/..)
include_directories(${LLDB_SOURCE_DIR}/source)
include_directories(MacOSX/DarwinLog)
include_directories(MacOSX)
#include_directories(${CMAKE_CURRENT_BINARY_DIR}/MacOSX)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist")
check_cxx_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments"
CXX_SUPPORTS_NO_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS)
if (CXX_SUPPORTS_NO_GNU_ZERO_VARIADIC_MACRO_ARGUMENTS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-gnu-zero-variadic-macro-arguments")
endif ()
check_cxx_compiler_flag("-Wno-zero-length-array"
CXX_SUPPORTS_NO_ZERO_LENGTH_ARRAY)
if (CXX_SUPPORTS_NO_ZERO_LENGTH_ARRAY)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-zero-length-array")
endif ()
check_cxx_compiler_flag("-Wno-extended-offsetof"
CXX_SUPPORTS_NO_EXTENDED_OFFSETOF)
if (CXX_SUPPORTS_NO_EXTENDED_OFFSETOF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-extended-offsetof")
endif ()
check_library_exists(compression compression_encode_buffer "" HAVE_LIBCOMPRESSION)
add_subdirectory(MacOSX)
set(generated_mach_interfaces
${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h
${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c
${CMAKE_CURRENT_BINARY_DIR}/mach_excUser.c
)
add_custom_command(OUTPUT ${generated_mach_interfaces}
COMMAND mig ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MacOSX/dbgnub-mig.defs
)
set(DEBUGSERVER_VERS_GENERATED_FILE ${CMAKE_CURRENT_BINARY_DIR}/debugserver_vers.c)
set_source_files_properties(${DEBUGSERVER_VERS_GENERATED_FILE} PROPERTIES GENERATED 1)
add_custom_command(OUTPUT ${DEBUGSERVER_VERS_GENERATED_FILE}
COMMAND ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl
${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj debugserver
> ${DEBUGSERVER_VERS_GENERATED_FILE}
DEPENDS ${LLDB_SOURCE_DIR}/scripts/generate-vers.pl
${LLDB_SOURCE_DIR}/lldb.xcodeproj/project.pbxproj
)
set(lldbDebugserverCommonSources
DNBArch.cpp
DNBBreakpoint.cpp
DNB.cpp
DNBDataRef.cpp
DNBError.cpp
DNBLog.cpp
DNBRegisterInfo.cpp
DNBThreadResumeActions.cpp
JSON.cpp
StdStringExtractor.cpp
# JSON reader depends on the following LLDB-common files
${LLDB_SOURCE_DIR}/source/Host/common/StringConvert.cpp
${LLDB_SOURCE_DIR}/source/Host/common/SocketAddress.cpp
# end JSON reader dependencies
libdebugserver.cpp
PseudoTerminal.cpp
PThreadEvent.cpp
PThreadMutex.cpp
RNBContext.cpp
RNBRemote.cpp
RNBServices.cpp
RNBSocket.cpp
SysSignal.cpp
TTYState.cpp
MacOSX/CFBundle.cpp
MacOSX/CFString.cpp
MacOSX/Genealogy.cpp
MacOSX/MachException.cpp
MacOSX/MachProcess.mm
MacOSX/MachTask.mm
MacOSX/MachThread.cpp
MacOSX/MachThreadList.cpp
MacOSX/MachVMMemory.cpp
MacOSX/MachVMRegion.cpp
MacOSX/OsLogger.cpp
${generated_mach_interfaces}
${DEBUGSERVER_VERS_GENERATED_FILE})
add_library(lldbDebugserverCommon ${lldbDebugserverCommonSources})
if (APPLE)
if(IOS)
find_library(BACKBOARD_LIBRARY BackBoardServices
PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
find_library(FRONTBOARD_LIBRARY FrontBoardServices
PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
find_library(SPRINGBOARD_LIBRARY SpringBoardServices
PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
find_library(MOBILESERVICES_LIBRARY MobileCoreServices
PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks)
find_library(LOCKDOWN_LIBRARY lockdown)
if(NOT BACKBOARD_LIBRARY)
set(SKIP_DEBUGSERVER True)
endif()
else()
find_library(COCOA_LIBRARY Cocoa)
endif()
endif()
if(HAVE_LIBCOMPRESSION)
set(LIBCOMPRESSION compression)
endif()
if(NOT SKIP_DEBUGSERVER)
target_link_libraries(lldbDebugserverCommon
INTERFACE ${COCOA_LIBRARY}
${CORE_FOUNDATION_LIBRARY}
${FOUNDATION_LIBRARY}
${BACKBOARD_LIBRARY}
${FRONTBOARD_LIBRARY}
${SPRINGBOARD_LIBRARY}
${MOBILESERVICES_LIBRARY}
${LOCKDOWN_LIBRARY}
lldbDebugserverArchSupport
lldbDebugserverDarwin_DarwinLog
${LIBCOMPRESSION})
if(HAVE_LIBCOMPRESSION)
set_property(TARGET lldbDebugserverCommon APPEND PROPERTY
COMPILE_DEFINITIONS HAVE_LIBCOMPRESSION)
endif()
set(LLVM_OPTIONAL_SOURCES ${lldbDebugserverCommonSources})
add_lldb_tool(debugserver INCLUDE_IN_FRAMEWORK
debugserver.cpp
LINK_LIBS
lldbDebugserverCommon
)
if(IOS)
set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_DEFINITIONS
WITH_LOCKDOWN
WITH_FBS
WITH_BKS
)
set_property(TARGET debugserver APPEND PROPERTY COMPILE_DEFINITIONS
WITH_LOCKDOWN
WITH_FBS
WITH_BKS
)
set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_FLAGS
-F${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks
)
endif()
endif()
if(IOS)
add_library(lldbDebugserverCommon_NonUI ${lldbDebugserverCommonSources})
target_link_libraries(lldbDebugserverCommon_NonUI
INTERFACE ${COCOA_LIBRARY}
${CORE_FOUNDATION_LIBRARY}
${FOUNDATION_LIBRARY}
lldbDebugserverArchSupport
lldbDebugserverDarwin_DarwinLog
${LIBCOMPRESSION})
if(HAVE_LIBCOMPRESSION)
set_property(TARGET lldbDebugserverCommon_NonUI APPEND PROPERTY
COMPILE_DEFINITIONS HAVE_LIBCOMPRESSION)
endif()
add_lldb_tool(debugserver-nonui
debugserver.cpp
LINK_LIBS
lldbDebugserverCommon_NonUI
)
endif()
set(entitlements_xml ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-macosx-entitlements.plist)
if(IOS)
set(entitlements_xml ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-entitlements.plist)
endif()
set(LLDB_CODESIGN_IDENTITY "lldb_codesign"
CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.")
set(LLDB_USE_ENTITLEMENTS_Default On)
if("${LLDB_CODESIGN_IDENTITY}" STREQUAL "lldb_codesign")
set(LLDB_USE_ENTITLEMENTS_Default Off)
endif()
option(LLDB_USE_ENTITLEMENTS "Use entitlements when codesigning (Defaults Off when using lldb_codesign identity, otherwise On)" ${LLDB_USE_ENTITLEMENTS_Default})
if (NOT ("${LLDB_CODESIGN_IDENTITY}" STREQUAL ""))
if(LLDB_USE_ENTITLEMENTS)
set(entitlements_flags --entitlements ${entitlements_xml})
endif()
execute_process(
COMMAND xcrun -f codesign_allocate
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE CODESIGN_ALLOCATE
)
add_custom_command(TARGET debugserver
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE}
codesign --force --sign ${LLDB_CODESIGN_IDENTITY}
${entitlements_flags}
$<TARGET_FILE:debugserver>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
if(IOS)
add_custom_command(TARGET debugserver-nonui
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE}
codesign --force --sign ${LLDB_CODESIGN_IDENTITY}
${entitlements_flags}
$<TARGET_FILE:debugserver>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
endif()
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,241 @@
//===-- DNB.h ---------------------------------------------------*- 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 3/23/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNB_h__
#define __DNB_h__
#include "DNBDefs.h"
#include "JSONGenerator.h"
#include "MacOSX/DarwinLog/DarwinLogEvent.h"
#include "MacOSX/Genealogy.h"
#include "MacOSX/ThreadInfo.h"
#include <mach/thread_info.h>
#include <string>
#define DNB_EXPORT __attribute__((visibility("default")))
#ifndef CPU_TYPE_ARM64
#define CPU_TYPE_ARM64 ((cpu_type_t)12 | 0x01000000)
#endif
typedef bool (*DNBShouldCancelCallback)(void *);
void DNBInitialize();
void DNBTerminate();
nub_bool_t DNBSetArchitecture(const char *arch);
//----------------------------------------------------------------------
// Process control
//----------------------------------------------------------------------
nub_process_t DNBProcessLaunch(
const char *path, char const *argv[], const char *envp[],
const char *working_directory, // NULL => don't change, non-NULL => set
// working directory for inferior to this
const char *stdin_path, const char *stdout_path, const char *stderr_path,
bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr,
const char *event_data, char *err_str, size_t err_len);
nub_process_t DNBProcessGetPIDByName(const char *name);
nub_process_t DNBProcessAttach(nub_process_t pid, struct timespec *timeout,
char *err_str, size_t err_len);
nub_process_t DNBProcessAttachByName(const char *name, struct timespec *timeout,
char *err_str, size_t err_len);
nub_process_t
DNBProcessAttachWait(const char *wait_name, nub_launch_flavor_t launch_flavor,
bool ignore_existing, struct timespec *timeout,
useconds_t interval, char *err_str, size_t err_len,
DNBShouldCancelCallback should_cancel = NULL,
void *callback_data = NULL);
// Resume a process with exact instructions on what to do with each thread:
// - If no thread actions are supplied (actions is NULL or num_actions is zero),
// then all threads are continued.
// - If any thread actions are supplied, then each thread will do as it is told
// by the action. A default actions for any threads that don't have an
// explicit thread action can be made by making a thread action with a tid of
// INVALID_NUB_THREAD. If there is no default action, those threads will
// remain stopped.
nub_bool_t DNBProcessResume(nub_process_t pid,
const DNBThreadResumeAction *actions,
size_t num_actions) DNB_EXPORT;
nub_bool_t DNBProcessHalt(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessDetach(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessSignal(nub_process_t pid, int signal) DNB_EXPORT;
nub_bool_t DNBProcessInterrupt(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessKill(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessSendEvent(nub_process_t pid, const char *event) DNB_EXPORT;
nub_size_t DNBProcessMemoryRead(nub_process_t pid, nub_addr_t addr,
nub_size_t size, void *buf) DNB_EXPORT;
uint64_t DNBProcessMemoryReadInteger(nub_process_t pid, nub_addr_t addr,
nub_size_t integer_size,
uint64_t fail_value) DNB_EXPORT;
nub_addr_t DNBProcessMemoryReadPointer(nub_process_t pid,
nub_addr_t addr) DNB_EXPORT;
std::string DNBProcessMemoryReadCString(nub_process_t pid,
nub_addr_t addr) DNB_EXPORT;
std::string
DNBProcessMemoryReadCStringFixed(nub_process_t pid, nub_addr_t addr,
nub_size_t fixed_length) DNB_EXPORT;
nub_size_t DNBProcessMemoryWrite(nub_process_t pid, nub_addr_t addr,
nub_size_t size, const void *buf) DNB_EXPORT;
nub_addr_t DNBProcessMemoryAllocate(nub_process_t pid, nub_size_t size,
uint32_t permissions) DNB_EXPORT;
nub_bool_t DNBProcessMemoryDeallocate(nub_process_t pid,
nub_addr_t addr) DNB_EXPORT;
int DNBProcessMemoryRegionInfo(nub_process_t pid, nub_addr_t addr,
DNBRegionInfo *region_info) DNB_EXPORT;
std::string
DNBProcessGetProfileData(nub_process_t pid,
DNBProfileDataScanType scanType) DNB_EXPORT;
nub_bool_t
DNBProcessSetEnableAsyncProfiling(nub_process_t pid, nub_bool_t enable,
uint64_t interval_usec,
DNBProfileDataScanType scan_type) DNB_EXPORT;
DarwinLogEventVector DNBProcessGetAvailableDarwinLogEvents(nub_process_t pid);
//----------------------------------------------------------------------
// Process status
//----------------------------------------------------------------------
nub_bool_t DNBProcessIsAlive(nub_process_t pid) DNB_EXPORT;
nub_state_t DNBProcessGetState(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessGetExitStatus(nub_process_t pid, int *status) DNB_EXPORT;
nub_bool_t DNBProcessSetExitStatus(nub_process_t pid, int status) DNB_EXPORT;
const char *DNBProcessGetExitInfo(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessSetExitInfo(nub_process_t pid,
const char *info) DNB_EXPORT;
nub_size_t DNBProcessGetNumThreads(nub_process_t pid) DNB_EXPORT;
nub_thread_t DNBProcessGetCurrentThread(nub_process_t pid) DNB_EXPORT;
nub_thread_t DNBProcessGetCurrentThreadMachPort(nub_process_t pid) DNB_EXPORT;
nub_thread_t DNBProcessSetCurrentThread(nub_process_t pid,
nub_thread_t tid) DNB_EXPORT;
nub_thread_t DNBProcessGetThreadAtIndex(nub_process_t pid,
nub_size_t thread_idx) DNB_EXPORT;
nub_bool_t DNBProcessSyncThreadState(nub_process_t pid,
nub_thread_t tid) DNB_EXPORT;
nub_addr_t DNBProcessGetSharedLibraryInfoAddress(nub_process_t pid) DNB_EXPORT;
nub_bool_t DNBProcessSharedLibrariesUpdated(nub_process_t pid) DNB_EXPORT;
nub_size_t
DNBProcessGetSharedLibraryInfo(nub_process_t pid, nub_bool_t only_changed,
DNBExecutableImageInfo **image_infos) DNB_EXPORT;
nub_bool_t DNBProcessSetNameToAddressCallback(nub_process_t pid,
DNBCallbackNameToAddress callback,
void *baton) DNB_EXPORT;
nub_bool_t DNBProcessSetSharedLibraryInfoCallback(
nub_process_t pid, DNBCallbackCopyExecutableImageInfos callback,
void *baton) DNB_EXPORT;
nub_addr_t DNBProcessLookupAddress(nub_process_t pid, const char *name,
const char *shlib) DNB_EXPORT;
nub_size_t DNBProcessGetAvailableSTDOUT(nub_process_t pid, char *buf,
nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetAvailableSTDERR(nub_process_t pid, char *buf,
nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetAvailableProfileData(nub_process_t pid, char *buf,
nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetStopCount(nub_process_t pid) DNB_EXPORT;
uint32_t DNBProcessGetCPUType(nub_process_t pid) DNB_EXPORT;
//----------------------------------------------------------------------
// Process executable and arguments
//----------------------------------------------------------------------
const char *DNBProcessGetExecutablePath(nub_process_t pid);
const char *DNBProcessGetArgumentAtIndex(nub_process_t pid, nub_size_t idx);
nub_size_t DNBProcessGetArgumentCount(nub_process_t pid);
//----------------------------------------------------------------------
// Process events
//----------------------------------------------------------------------
nub_event_t DNBProcessWaitForEvents(nub_process_t pid, nub_event_t event_mask,
bool wait_for_set,
struct timespec *timeout);
void DNBProcessResetEvents(nub_process_t pid, nub_event_t event_mask);
//----------------------------------------------------------------------
// Thread functions
//----------------------------------------------------------------------
const char *DNBThreadGetName(nub_process_t pid, nub_thread_t tid);
nub_bool_t
DNBThreadGetIdentifierInfo(nub_process_t pid, nub_thread_t tid,
thread_identifier_info_data_t *ident_info);
nub_state_t DNBThreadGetState(nub_process_t pid, nub_thread_t tid);
nub_bool_t DNBThreadGetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
uint32_t set, uint32_t reg,
DNBRegisterValue *value);
nub_bool_t DNBThreadSetRegisterValueByID(nub_process_t pid, nub_thread_t tid,
uint32_t set, uint32_t reg,
const DNBRegisterValue *value);
nub_size_t DNBThreadGetRegisterContext(nub_process_t pid, nub_thread_t tid,
void *buf, size_t buf_len);
nub_size_t DNBThreadSetRegisterContext(nub_process_t pid, nub_thread_t tid,
const void *buf, size_t buf_len);
uint32_t DNBThreadSaveRegisterState(nub_process_t pid, nub_thread_t tid);
nub_bool_t DNBThreadRestoreRegisterState(nub_process_t pid, nub_thread_t tid,
uint32_t save_id);
nub_bool_t DNBThreadGetRegisterValueByName(nub_process_t pid, nub_thread_t tid,
uint32_t set, const char *name,
DNBRegisterValue *value);
nub_bool_t DNBThreadGetStopReason(nub_process_t pid, nub_thread_t tid,
DNBThreadStopInfo *stop_info);
const char *DNBThreadGetInfo(nub_process_t pid, nub_thread_t tid);
Genealogy::ThreadActivitySP DNBGetGenealogyInfoForThread(nub_process_t pid,
nub_thread_t tid,
bool &timed_out);
Genealogy::ProcessExecutableInfoSP DNBGetGenealogyImageInfo(nub_process_t pid,
size_t idx);
ThreadInfo::QoS DNBGetRequestedQoSForThread(nub_process_t pid, nub_thread_t tid,
nub_addr_t tsd,
uint64_t dti_qos_class_index);
nub_addr_t DNBGetPThreadT(nub_process_t pid, nub_thread_t tid);
nub_addr_t DNBGetDispatchQueueT(nub_process_t pid, nub_thread_t tid);
nub_addr_t
DNBGetTSDAddressForThread(nub_process_t pid, nub_thread_t tid,
uint64_t plo_pthread_tsd_base_address_offset,
uint64_t plo_pthread_tsd_base_offset,
uint64_t plo_pthread_tsd_entry_size);
JSONGenerator::ObjectSP DNBGetLoadedDynamicLibrariesInfos(
nub_process_t pid, nub_addr_t image_list_address, nub_addr_t image_count);
JSONGenerator::ObjectSP DNBGetAllLoadedLibrariesInfos(nub_process_t pid);
JSONGenerator::ObjectSP
DNBGetLibrariesInfoForAddresses(nub_process_t pid,
std::vector<uint64_t> &macho_addresses);
JSONGenerator::ObjectSP DNBGetSharedCacheInfo(nub_process_t pid);
//
//----------------------------------------------------------------------
// Breakpoint functions
//----------------------------------------------------------------------
nub_bool_t DNBBreakpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
nub_bool_t hardware);
nub_bool_t DNBBreakpointClear(nub_process_t pid, nub_addr_t addr);
//----------------------------------------------------------------------
// Watchpoint functions
//----------------------------------------------------------------------
nub_bool_t DNBWatchpointSet(nub_process_t pid, nub_addr_t addr, nub_size_t size,
uint32_t watch_flags, nub_bool_t hardware);
nub_bool_t DNBWatchpointClear(nub_process_t pid, nub_addr_t addr);
uint32_t DNBWatchpointGetNumSupportedHWP(nub_process_t pid);
uint32_t DNBGetRegisterCPUType();
const DNBRegisterSetInfo *DNBGetRegisterSetInfo(nub_size_t *num_reg_sets);
nub_bool_t DNBGetRegisterInfoByName(const char *reg_name,
DNBRegisterInfo *info);
//----------------------------------------------------------------------
// Other static nub information calls.
//----------------------------------------------------------------------
const char *DNBStateAsString(nub_state_t state);
nub_bool_t DNBResolveExecutablePath(const char *path, char *resolved_path,
size_t resolved_path_size);
bool DNBGetOSVersionNumbers(uint64_t *major, uint64_t *minor, uint64_t *patch);
#endif

View File

@@ -0,0 +1,80 @@
//===-- DNBArch.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 6/24/07.
//
//===----------------------------------------------------------------------===//
#include "DNBArch.h"
#include <assert.h>
#include <mach/mach.h>
#include <map>
#include "DNBLog.h"
typedef std::map<uint32_t, DNBArchPluginInfo> CPUPluginInfoMap;
static uint32_t g_current_cpu_type = 0;
CPUPluginInfoMap g_arch_plugins;
static const DNBArchPluginInfo *GetArchInfo() {
CPUPluginInfoMap::const_iterator pos =
g_arch_plugins.find(g_current_cpu_type);
if (pos != g_arch_plugins.end())
return &pos->second;
return NULL;
}
uint32_t DNBArchProtocol::GetArchitecture() { return g_current_cpu_type; }
bool DNBArchProtocol::SetArchitecture(uint32_t cpu_type) {
g_current_cpu_type = cpu_type;
bool result = g_arch_plugins.find(g_current_cpu_type) != g_arch_plugins.end();
DNBLogThreadedIf(
LOG_PROCESS,
"DNBArchProtocol::SetDefaultArchitecture (cpu_type=0x%8.8x) => %i",
cpu_type, result);
return result;
}
void DNBArchProtocol::RegisterArchPlugin(const DNBArchPluginInfo &arch_info) {
if (arch_info.cpu_type)
g_arch_plugins[arch_info.cpu_type] = arch_info;
}
uint32_t DNBArchProtocol::GetRegisterCPUType() {
const DNBArchPluginInfo *arch_info = GetArchInfo();
if (arch_info)
return arch_info->cpu_type;
return 0;
}
const DNBRegisterSetInfo *
DNBArchProtocol::GetRegisterSetInfo(nub_size_t *num_reg_sets) {
const DNBArchPluginInfo *arch_info = GetArchInfo();
if (arch_info)
return arch_info->GetRegisterSetInfo(num_reg_sets);
*num_reg_sets = 0;
return NULL;
}
DNBArchProtocol *DNBArchProtocol::Create(MachThread *thread) {
const DNBArchPluginInfo *arch_info = GetArchInfo();
if (arch_info)
return arch_info->Create(thread);
return NULL;
}
const uint8_t *DNBArchProtocol::GetBreakpointOpcode(nub_size_t byte_size) {
const DNBArchPluginInfo *arch_info = GetArchInfo();
if (arch_info)
return arch_info->GetBreakpointOpcode(byte_size);
return NULL;
}

View File

@@ -0,0 +1,127 @@
//===-- DNBArch.h -----------------------------------------------*- 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 6/24/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DebugNubArch_h__
#define __DebugNubArch_h__
#include "DNBDefs.h"
#include "MacOSX/MachException.h"
#include <mach/mach.h>
#include <stdio.h>
struct DNBRegisterValue;
struct DNBRegisterSetInfo;
class DNBArchProtocol;
class MachThread;
typedef DNBArchProtocol *(*DNBArchCallbackCreate)(MachThread *thread);
typedef const DNBRegisterSetInfo *(*DNBArchCallbackGetRegisterSetInfo)(
nub_size_t *num_reg_sets);
typedef const uint8_t *(*DNBArchCallbackGetBreakpointOpcode)(
nub_size_t byte_size);
typedef struct DNBArchPluginInfoTag {
uint32_t cpu_type;
DNBArchCallbackCreate Create;
DNBArchCallbackGetRegisterSetInfo GetRegisterSetInfo;
DNBArchCallbackGetBreakpointOpcode GetBreakpointOpcode;
} DNBArchPluginInfo;
class DNBArchProtocol {
public:
static DNBArchProtocol *Create(MachThread *thread);
static uint32_t GetRegisterCPUType();
static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);
static const uint8_t *GetBreakpointOpcode(nub_size_t byte_size);
static void RegisterArchPlugin(const DNBArchPluginInfo &arch_info);
static uint32_t GetArchitecture();
static bool SetArchitecture(uint32_t cpu_type);
DNBArchProtocol() : m_save_id(0) {}
virtual ~DNBArchProtocol() {}
virtual bool GetRegisterValue(uint32_t set, uint32_t reg,
DNBRegisterValue *value) = 0;
virtual bool SetRegisterValue(uint32_t set, uint32_t reg,
const DNBRegisterValue *value) = 0;
virtual nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len) = 0;
virtual nub_size_t SetRegisterContext(const void *buf,
nub_size_t buf_len) = 0;
virtual uint32_t SaveRegisterState() = 0;
virtual bool RestoreRegisterState(uint32_t save_id) = 0;
virtual kern_return_t GetRegisterState(int set, bool force) = 0;
virtual kern_return_t SetRegisterState(int set) = 0;
virtual bool RegisterSetStateIsValid(int set) const = 0;
virtual uint64_t GetPC(uint64_t failValue) = 0; // Get program counter
virtual kern_return_t SetPC(uint64_t value) = 0;
virtual uint64_t GetSP(uint64_t failValue) = 0; // Get stack pointer
virtual void ThreadWillResume() = 0;
virtual bool ThreadDidStop() = 0;
virtual bool NotifyException(MachException::Data &exc) { return false; }
virtual uint32_t NumSupportedHardwareBreakpoints() { return 0; }
virtual uint32_t NumSupportedHardwareWatchpoints() { return 0; }
virtual uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size) {
return INVALID_NUB_HW_INDEX;
}
virtual uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,
bool read, bool write,
bool also_set_on_task) {
return INVALID_NUB_HW_INDEX;
}
virtual bool DisableHardwareBreakpoint(uint32_t hw_index) { return false; }
virtual bool DisableHardwareWatchpoint(uint32_t hw_index,
bool also_set_on_task) {
return false;
}
virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr) {
return INVALID_NUB_HW_INDEX;
}
virtual bool StepNotComplete() { return false; }
protected:
friend class MachThread;
uint32_t GetNextRegisterStateSaveID() { return ++m_save_id; }
enum {
Trans_Pending =
0, // Transaction is pending, and checkpoint state has been snapshotted.
Trans_Done = 1, // Transaction is done, the current state is committed, and
// checkpoint state is irrelevant.
Trans_Rolled_Back = 2 // Transaction is done, the current state has been
// rolled back to the checkpoint state.
};
virtual bool StartTransForHWP() { return true; }
virtual bool RollbackTransForHWP() { return true; }
virtual bool FinishTransForHWP() { return true; }
uint32_t m_save_id; // An always incrementing integer ID used with
// SaveRegisterState/RestoreRegisterState
};
#include "MacOSX/arm/DNBArchImpl.h"
#include "MacOSX/arm64/DNBArchImplARM64.h"
#include "MacOSX/i386/DNBArchImplI386.h"
#include "MacOSX/ppc/DNBArchImpl.h"
#include "MacOSX/x86_64/DNBArchImplX86_64.h"
#endif

View File

@@ -0,0 +1,178 @@
//===-- DNBBreakpoint.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 6/29/07.
//
//===----------------------------------------------------------------------===//
#include "DNBBreakpoint.h"
#include "DNBLog.h"
#include "MachProcess.h"
#include <algorithm>
#include <assert.h>
#include <inttypes.h>
#pragma mark-- DNBBreakpoint
DNBBreakpoint::DNBBreakpoint(nub_addr_t addr, nub_size_t byte_size,
bool hardware)
: m_retain_count(1), m_byte_size(static_cast<uint32_t>(byte_size)),
m_opcode(), m_addr(addr), m_enabled(0), m_hw_preferred(hardware),
m_is_watchpoint(0), m_watch_read(0), m_watch_write(0),
m_hw_index(INVALID_NUB_HW_INDEX) {}
DNBBreakpoint::~DNBBreakpoint() {}
void DNBBreakpoint::Dump() const {
if (IsBreakpoint()) {
DNBLog("DNBBreakpoint addr = 0x%llx state = %s type = %s breakpoint "
"hw_index = %i",
(uint64_t)m_addr, m_enabled ? "enabled " : "disabled",
IsHardware() ? "hardware" : "software", GetHardwareIndex());
} else {
DNBLog("DNBBreakpoint addr = 0x%llx size = %llu state = %s type = %s "
"watchpoint (%s%s) hw_index = %i",
(uint64_t)m_addr, (uint64_t)m_byte_size,
m_enabled ? "enabled " : "disabled",
IsHardware() ? "hardware" : "software", m_watch_read ? "r" : "",
m_watch_write ? "w" : "", GetHardwareIndex());
}
}
#pragma mark-- DNBBreakpointList
DNBBreakpointList::DNBBreakpointList() {}
DNBBreakpointList::~DNBBreakpointList() {}
DNBBreakpoint *DNBBreakpointList::Add(nub_addr_t addr, nub_size_t length,
bool hardware) {
m_breakpoints.insert(
std::make_pair(addr, DNBBreakpoint(addr, length, hardware)));
iterator pos = m_breakpoints.find(addr);
return &pos->second;
}
bool DNBBreakpointList::Remove(nub_addr_t addr) {
iterator pos = m_breakpoints.find(addr);
if (pos != m_breakpoints.end()) {
m_breakpoints.erase(pos);
return true;
}
return false;
}
DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) {
iterator pos = m_breakpoints.find(addr);
if (pos != m_breakpoints.end())
return &pos->second;
return NULL;
}
const DNBBreakpoint *DNBBreakpointList::FindByAddress(nub_addr_t addr) const {
const_iterator pos = m_breakpoints.find(addr);
if (pos != m_breakpoints.end())
return &pos->second;
return NULL;
}
// Finds the next breakpoint at an address greater than or equal to "addr"
size_t DNBBreakpointList::FindBreakpointsThatOverlapRange(
nub_addr_t addr, nub_addr_t size, std::vector<DNBBreakpoint *> &bps) {
bps.clear();
iterator end = m_breakpoints.end();
// Find the first breakpoint with an address >= to "addr"
iterator pos = m_breakpoints.lower_bound(addr);
if (pos != end) {
if (pos != m_breakpoints.begin()) {
// Watch out for a breakpoint at an address less than "addr" that might
// still overlap
iterator prev_pos = pos;
--prev_pos;
if (prev_pos->second.IntersectsRange(addr, size, NULL, NULL, NULL))
bps.push_back(&pos->second);
}
while (pos != end) {
// When we hit a breakpoint whose start address is greater than "addr +
// size" we are done.
// Do the math in a way that doesn't risk unsigned overflow with bad
// input.
if ((pos->second.Address() - addr) >= size)
break;
// Check if this breakpoint overlaps, and if it does, add it to the list
if (pos->second.IntersectsRange(addr, size, NULL, NULL, NULL)) {
bps.push_back(&pos->second);
++pos;
}
}
}
return bps.size();
}
void DNBBreakpointList::Dump() const {
const_iterator pos;
const_iterator end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
pos->second.Dump();
}
void DNBBreakpointList::DisableAll() {
iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
pos->second.SetEnabled(false);
}
void DNBBreakpointList::RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size,
void *p) const {
uint8_t *buf = (uint8_t *)p;
const_iterator end = m_breakpoints.end();
const_iterator pos = m_breakpoints.lower_bound(addr);
while (pos != end && (pos->first < (addr + size))) {
nub_addr_t intersect_addr;
nub_size_t intersect_size;
nub_size_t opcode_offset;
const DNBBreakpoint &bp = pos->second;
if (bp.IntersectsRange(addr, size, &intersect_addr, &intersect_size,
&opcode_offset)) {
assert(addr <= intersect_addr && intersect_addr < addr + size);
assert(addr < intersect_addr + intersect_size &&
intersect_addr + intersect_size <= addr + size);
assert(opcode_offset + intersect_size <= bp.ByteSize());
nub_size_t buf_offset = intersect_addr - addr;
::memcpy(buf + buf_offset, bp.SavedOpcodeBytes() + opcode_offset,
intersect_size);
}
++pos;
}
}
void DNBBreakpointList::DisableAllBreakpoints(MachProcess *process) {
iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
process->DisableBreakpoint(pos->second.Address(), false);
}
void DNBBreakpointList::DisableAllWatchpoints(MachProcess *process) {
iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
process->DisableWatchpoint(pos->second.Address(), false);
}
void DNBBreakpointList::RemoveDisabled() {
iterator pos = m_breakpoints.begin();
while (pos != m_breakpoints.end()) {
if (!pos->second.IsEnabled())
pos = m_breakpoints.erase(pos);
else
++pos;
}
}

View File

@@ -0,0 +1,149 @@
//===-- DNBBreakpoint.h -----------------------------------------*- 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 6/29/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBBreakpoint_h__
#define __DNBBreakpoint_h__
#include <mach/mach.h>
#include <map>
#include <vector>
#include "DNBDefs.h"
class MachProcess;
class DNBBreakpoint {
public:
DNBBreakpoint(nub_addr_t m_addr, nub_size_t byte_size, bool hardware);
~DNBBreakpoint();
nub_size_t ByteSize() const { return m_byte_size; }
uint8_t *SavedOpcodeBytes() { return &m_opcode[0]; }
const uint8_t *SavedOpcodeBytes() const { return &m_opcode[0]; }
nub_addr_t Address() const { return m_addr; }
// nub_thread_t ThreadID() const { return m_tid; }
bool IsEnabled() const { return m_enabled; }
bool IntersectsRange(nub_addr_t addr, nub_size_t size,
nub_addr_t *intersect_addr, nub_size_t *intersect_size,
nub_size_t *opcode_offset) const {
// We only use software traps for software breakpoints
if (IsBreakpoint() && IsEnabled() && !IsHardware()) {
if (m_byte_size > 0) {
const nub_addr_t bp_end_addr = m_addr + m_byte_size;
const nub_addr_t end_addr = addr + size;
// Is the breakpoint end address before the passed in start address?
if (bp_end_addr <= addr)
return false;
// Is the breakpoint start address after passed in end address?
if (end_addr <= m_addr)
return false;
if (intersect_addr || intersect_size || opcode_offset) {
if (m_addr < addr) {
if (intersect_addr)
*intersect_addr = addr;
if (intersect_size)
*intersect_size =
std::min<nub_addr_t>(bp_end_addr, end_addr) - addr;
if (opcode_offset)
*opcode_offset = addr - m_addr;
} else {
if (intersect_addr)
*intersect_addr = m_addr;
if (intersect_size)
*intersect_size =
std::min<nub_addr_t>(bp_end_addr, end_addr) - m_addr;
if (opcode_offset)
*opcode_offset = 0;
}
}
return true;
}
}
return false;
}
void SetEnabled(bool enabled) {
if (!enabled)
SetHardwareIndex(INVALID_NUB_HW_INDEX);
m_enabled = enabled;
}
void SetIsWatchpoint(uint32_t type) {
m_is_watchpoint = 1;
m_watch_read = (type & WATCH_TYPE_READ) != 0;
m_watch_write = (type & WATCH_TYPE_WRITE) != 0;
}
bool IsBreakpoint() const { return m_is_watchpoint == 0; }
bool IsWatchpoint() const { return m_is_watchpoint == 1; }
bool WatchpointRead() const { return m_watch_read != 0; }
bool WatchpointWrite() const { return m_watch_write != 0; }
bool HardwarePreferred() const { return m_hw_preferred; }
bool IsHardware() const { return m_hw_index != INVALID_NUB_HW_INDEX; }
uint32_t GetHardwareIndex() const { return m_hw_index; }
void SetHardwareIndex(uint32_t hw_index) { m_hw_index = hw_index; }
void Dump() const;
uint32_t Retain() { return ++m_retain_count; }
uint32_t Release() {
if (m_retain_count == 0)
return 0;
return --m_retain_count;
}
private:
uint32_t m_retain_count; // Each breakpoint is maintained by address and is
// ref counted in case multiple people set a
// breakpoint at the same address
uint32_t m_byte_size; // Length in bytes of the breakpoint if set in memory
uint8_t m_opcode[8]; // Saved opcode bytes
nub_addr_t m_addr; // Address of this breakpoint
uint32_t m_enabled : 1, // Flags for this breakpoint
m_hw_preferred : 1, // 1 if this point has been requested to be set using
// hardware (which may fail due to lack of resources)
m_is_watchpoint : 1, // 1 if this is a watchpoint
m_watch_read : 1, // 1 if we stop when the watched data is read from
m_watch_write : 1; // 1 if we stop when the watched data is written to
uint32_t
m_hw_index; // The hardware resource index for this breakpoint/watchpoint
};
class DNBBreakpointList {
public:
DNBBreakpointList();
~DNBBreakpointList();
DNBBreakpoint *Add(nub_addr_t addr, nub_size_t length, bool hardware);
bool Remove(nub_addr_t addr);
DNBBreakpoint *FindByAddress(nub_addr_t addr);
const DNBBreakpoint *FindByAddress(nub_addr_t addr) const;
size_t FindBreakpointsThatOverlapRange(nub_addr_t addr, nub_addr_t size,
std::vector<DNBBreakpoint *> &bps);
void Dump() const;
size_t Size() const { return m_breakpoints.size(); }
void DisableAll();
void RemoveTrapsFromBuffer(nub_addr_t addr, nub_size_t size, void *buf) const;
void DisableAllBreakpoints(MachProcess *process);
void DisableAllWatchpoints(MachProcess *process);
void RemoveDisabled();
protected:
typedef std::map<nub_addr_t, DNBBreakpoint> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
collection m_breakpoints;
};
#endif

View File

@@ -0,0 +1,351 @@
//===-- DNBDataRef.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 1/11/06.
//
//===----------------------------------------------------------------------===//
#include "DNBDataRef.h"
#include "DNBLog.h"
#include <assert.h>
#include <ctype.h>
#include <libkern/OSByteOrder.h>
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
DNBDataRef::DNBDataRef()
: m_start(NULL), m_end(NULL), m_swap(false), m_ptrSize(0),
m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
m_addrDATA(INVALID_NUB_ADDRESS) {}
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
DNBDataRef::DNBDataRef(const uint8_t *start, size_t size, bool swap)
: m_start(start), m_end(start + size), m_swap(swap), m_ptrSize(0),
m_addrPCRelative(INVALID_NUB_ADDRESS), m_addrTEXT(INVALID_NUB_ADDRESS),
m_addrDATA(INVALID_NUB_ADDRESS) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
DNBDataRef::~DNBDataRef() {}
//----------------------------------------------------------------------
// Get8
//----------------------------------------------------------------------
uint8_t DNBDataRef::Get8(offset_t *offset_ptr) const {
uint8_t val = 0;
if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
val = *(m_start + *offset_ptr);
*offset_ptr += sizeof(val);
}
return val;
}
//----------------------------------------------------------------------
// Get16
//----------------------------------------------------------------------
uint16_t DNBDataRef::Get16(offset_t *offset_ptr) const {
uint16_t val = 0;
if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
const uint8_t *p = m_start + *offset_ptr;
memcpy(&val, p, sizeof(uint16_t));
if (m_swap)
val = OSSwapInt16(val);
// Advance the offset
*offset_ptr += sizeof(val);
}
return val;
}
//----------------------------------------------------------------------
// Get32
//----------------------------------------------------------------------
uint32_t DNBDataRef::Get32(offset_t *offset_ptr) const {
uint32_t val = 0;
if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
const uint8_t *p = m_start + *offset_ptr;
memcpy(&val, p, sizeof(uint32_t));
if (m_swap)
val = OSSwapInt32(val);
// Advance the offset
*offset_ptr += sizeof(val);
}
return val;
}
//----------------------------------------------------------------------
// Get64
//----------------------------------------------------------------------
uint64_t DNBDataRef::Get64(offset_t *offset_ptr) const {
uint64_t val = 0;
if (ValidOffsetForDataOfSize(*offset_ptr, sizeof(val))) {
const uint8_t *p = m_start + *offset_ptr;
memcpy(&val, p, sizeof(uint64_t));
if (m_swap)
val = OSSwapInt64(val);
// Advance the offset
*offset_ptr += sizeof(val);
}
return val;
}
//----------------------------------------------------------------------
// GetMax32
//
// Used for calls when the size can vary. Fill in extra cases if they
// are ever needed.
//----------------------------------------------------------------------
uint32_t DNBDataRef::GetMax32(offset_t *offset_ptr, uint32_t byte_size) const {
switch (byte_size) {
case 1:
return Get8(offset_ptr);
break;
case 2:
return Get16(offset_ptr);
break;
case 4:
return Get32(offset_ptr);
break;
default:
assert(false && "GetMax32 unhandled case!");
break;
}
return 0;
}
//----------------------------------------------------------------------
// GetMax64
//
// Used for calls when the size can vary. Fill in extra cases if they
// are ever needed.
//----------------------------------------------------------------------
uint64_t DNBDataRef::GetMax64(offset_t *offset_ptr, uint32_t size) const {
switch (size) {
case 1:
return Get8(offset_ptr);
break;
case 2:
return Get16(offset_ptr);
break;
case 4:
return Get32(offset_ptr);
break;
case 8:
return Get64(offset_ptr);
break;
default:
assert(false && "GetMax64 unhandled case!");
break;
}
return 0;
}
//----------------------------------------------------------------------
// GetPointer
//
// Extract a pointer value from the buffer. The pointer size must be
// set prior to using this using one of the SetPointerSize functions.
//----------------------------------------------------------------------
uint64_t DNBDataRef::GetPointer(offset_t *offset_ptr) const {
// Must set pointer size prior to using this call
assert(m_ptrSize != 0);
return GetMax64(offset_ptr, m_ptrSize);
}
//----------------------------------------------------------------------
// GetCStr
//----------------------------------------------------------------------
const char *DNBDataRef::GetCStr(offset_t *offset_ptr,
uint32_t fixed_length) const {
const char *s = NULL;
if (m_start < m_end) {
s = (const char *)m_start + *offset_ptr;
// Advance the offset
if (fixed_length)
*offset_ptr += fixed_length;
else
*offset_ptr += strlen(s) + 1;
}
return s;
}
//----------------------------------------------------------------------
// GetData
//----------------------------------------------------------------------
const uint8_t *DNBDataRef::GetData(offset_t *offset_ptr,
uint32_t length) const {
const uint8_t *data = NULL;
if (length > 0 && ValidOffsetForDataOfSize(*offset_ptr, length)) {
data = m_start + *offset_ptr;
*offset_ptr += length;
}
return data;
}
//----------------------------------------------------------------------
// Get_ULEB128
//----------------------------------------------------------------------
uint64_t DNBDataRef::Get_ULEB128(offset_t *offset_ptr) const {
uint64_t result = 0;
if (m_start < m_end) {
int shift = 0;
const uint8_t *src = m_start + *offset_ptr;
uint8_t byte;
int bytecount = 0;
while (src < m_end) {
bytecount++;
byte = *src++;
result |= (uint64_t)(byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
}
*offset_ptr += bytecount;
}
return result;
}
//----------------------------------------------------------------------
// Get_SLEB128
//----------------------------------------------------------------------
int64_t DNBDataRef::Get_SLEB128(offset_t *offset_ptr) const {
int64_t result = 0;
if (m_start < m_end) {
int shift = 0;
int size = sizeof(uint32_t) * 8;
const uint8_t *src = m_start + *offset_ptr;
uint8_t byte = 0;
int bytecount = 0;
while (src < m_end) {
bytecount++;
byte = *src++;
result |= (int64_t)(byte & 0x7f) << shift;
shift += 7;
if ((byte & 0x80) == 0)
break;
}
// Sign bit of byte is 2nd high order bit (0x40)
if (shift < size && (byte & 0x40))
result |= -(1ll << shift);
*offset_ptr += bytecount;
}
return result;
}
//----------------------------------------------------------------------
// Skip_LEB128
//
// Skips past ULEB128 and SLEB128 numbers (just updates the offset)
//----------------------------------------------------------------------
void DNBDataRef::Skip_LEB128(offset_t *offset_ptr) const {
if (m_start < m_end) {
const uint8_t *start = m_start + *offset_ptr;
const uint8_t *src = start;
while ((src < m_end) && (*src++ & 0x80))
/* Do nothing */;
*offset_ptr += src - start;
}
}
uint32_t DNBDataRef::Dump(uint32_t startOffset, uint32_t endOffset,
uint64_t offsetBase, DNBDataRef::Type type,
uint32_t numPerLine, const char *format) {
uint32_t offset;
uint32_t count;
char str[1024];
str[0] = '\0';
size_t str_offset = 0;
for (offset = startOffset, count = 0;
ValidOffset(offset) && offset < endOffset; ++count) {
if ((count % numPerLine) == 0) {
// Print out any previous string
if (str[0] != '\0')
DNBLog("%s", str);
// Reset string offset and fill the current line string with address:
str_offset = 0;
str_offset += snprintf(str, sizeof(str), "0x%8.8llx:",
(uint64_t)(offsetBase + (offset - startOffset)));
}
// Make sure we don't pass the bounds of our current string buffer on each
// iteration through this loop
if (str_offset >= sizeof(str)) {
// The last snprintf consumed our string buffer, we will need to dump this
// out
// and reset the string with no address
DNBLog("%s", str);
str_offset = 0;
str[0] = '\0';
}
// We already checked that there is at least some room in the string str
// above, so it is safe to make
// the snprintf call each time through this loop
switch (type) {
case TypeUInt8:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %2.2x", Get8(&offset));
break;
case TypeChar: {
char ch = Get8(&offset);
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %c", isprint(ch) ? ch : ' ');
} break;
case TypeUInt16:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %4.4x", Get16(&offset));
break;
case TypeUInt32:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %8.8x", Get32(&offset));
break;
case TypeUInt64:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %16.16llx", Get64(&offset));
break;
case TypePointer:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " 0x%llx", GetPointer(&offset));
break;
case TypeULEB128:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " 0x%llx", Get_ULEB128(&offset));
break;
case TypeSLEB128:
str_offset += snprintf(str + str_offset, sizeof(str) - str_offset,
format ? format : " %lld", Get_SLEB128(&offset));
break;
}
}
if (str[0] != '\0')
DNBLog("%s", str);
return offset; // Return the offset at which we ended up
}

View File

@@ -0,0 +1,125 @@
//===-- DNBDataRef.h --------------------------------------------*- 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 1/11/06.
//
//===----------------------------------------------------------------------===//
//
// DNBDataRef is a class that can extract data in normal or byte
// swapped order from a data buffer that someone else owns. The data
// buffer needs to remain intact as long as the DNBDataRef object
// needs the data. Strings returned are pointers into the data buffer
// and will need to be copied if they are needed after the data buffer
// is no longer around.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBDataRef_h__
#define __DNBDataRef_h__
#include "DNBDefs.h"
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
class DNBDataRef {
public:
// For use with Dump
typedef enum {
TypeUInt8 = 0,
TypeChar,
TypeUInt16,
TypeUInt32,
TypeUInt64,
TypePointer,
TypeULEB128,
TypeSLEB128
} Type;
typedef uint32_t offset_t;
typedef nub_addr_t addr_t;
DNBDataRef();
DNBDataRef(const uint8_t *start, size_t size, bool swap);
~DNBDataRef();
void Clear() {
DNBDataRef::SetData(NULL, 0);
m_swap = false;
}
size_t BytesLeft(size_t offset) const {
const size_t size = GetSize();
if (size > offset)
return size - offset;
return 0;
}
bool ValidOffset(offset_t offset) const { return BytesLeft(offset) > 0; }
bool ValidOffsetForDataOfSize(offset_t offset, uint32_t num_bytes) const {
return num_bytes <= BytesLeft(offset);
}
size_t GetSize() const { return m_end - m_start; }
const uint8_t *GetDataStart() const { return m_start; }
const uint8_t *GetDataEnd() const { return m_end; }
bool GetSwap() const { return m_swap; }
void SetSwap(bool swap) { m_swap = swap; }
void SetData(const uint8_t *start, size_t size) {
m_start = start;
if (m_start != NULL)
m_end = start + size;
else
m_end = NULL;
}
uint8_t GetPointerSize() const { return m_ptrSize; }
void SetPointerSize(uint8_t size) { m_ptrSize = size; }
void SetEHPtrBaseAddrPCRelative(addr_t addr = INVALID_NUB_ADDRESS) {
m_addrPCRelative = addr;
}
void SetEHPtrBaseAddrTEXT(addr_t addr = INVALID_NUB_ADDRESS) {
m_addrTEXT = addr;
}
void SetEHPtrBaseAddrDATA(addr_t addr = INVALID_NUB_ADDRESS) {
m_addrDATA = addr;
}
uint8_t Get8(offset_t *offset_ptr) const;
uint16_t Get16(offset_t *offset_ptr) const;
uint32_t Get32(offset_t *offset_ptr) const;
uint64_t Get64(offset_t *offset_ptr) const;
uint32_t GetMax32(offset_t *offset_ptr, uint32_t byte_size) const;
uint64_t GetMax64(offset_t *offset_ptr, uint32_t byte_size) const;
uint64_t GetPointer(offset_t *offset_ptr) const;
// uint64_t GetDwarfEHPtr(offset_t *offset_ptr, uint32_t eh_ptr_enc)
// const;
const char *GetCStr(offset_t *offset_ptr, uint32_t fixed_length = 0) const;
const char *PeekCStr(offset_t offset) const {
if (ValidOffset(offset))
return (const char *)m_start + offset;
return NULL;
}
const uint8_t *GetData(offset_t *offset_ptr, uint32_t length) const;
uint64_t Get_ULEB128(offset_t *offset_ptr) const;
int64_t Get_SLEB128(offset_t *offset_ptr) const;
void Skip_LEB128(offset_t *offset_ptr) const;
uint32_t Dump(offset_t startOffset, offset_t endOffset, uint64_t offsetBase,
DNBDataRef::Type type, uint32_t numPerLine,
const char *typeFormat = NULL);
protected:
const uint8_t *m_start;
const uint8_t *m_end;
bool m_swap;
uint8_t m_ptrSize;
addr_t m_addrPCRelative;
addr_t m_addrTEXT;
addr_t m_addrDATA;
};
#endif // #ifndef __DNBDataRef_h__

View File

@@ -0,0 +1,373 @@
//===-- DNBDefs.h -----------------------------------------------*- 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 6/26/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBDefs_h__
#define __DNBDefs_h__
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/syslimits.h>
#include <unistd.h>
//----------------------------------------------------------------------
// Define nub_addr_t and the invalid address value from the architecture
//----------------------------------------------------------------------
#if defined(__x86_64__) || defined(__ppc64__) || defined(__arm64__) || \
defined(__aarch64__)
//----------------------------------------------------------------------
// 64 bit address architectures
//----------------------------------------------------------------------
typedef uint64_t nub_addr_t;
#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
#elif defined(__i386__) || defined(__powerpc__) || defined(__ppc__) || \
defined(__arm__)
//----------------------------------------------------------------------
// 32 bit address architectures
//----------------------------------------------------------------------
typedef uint32_t nub_addr_t;
#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ul)
#else
//----------------------------------------------------------------------
// Default to 64 bit address for unrecognized architectures.
//----------------------------------------------------------------------
#warning undefined architecture, defaulting to 8 byte addresses
typedef uint64_t nub_addr_t;
#define INVALID_NUB_ADDRESS ((nub_addr_t)~0ull)
#endif
typedef size_t nub_size_t;
typedef ssize_t nub_ssize_t;
typedef uint32_t nub_index_t;
typedef pid_t nub_process_t;
typedef uint64_t nub_thread_t;
typedef uint32_t nub_event_t;
typedef uint32_t nub_bool_t;
#define INVALID_NUB_PROCESS ((nub_process_t)0)
#define INVALID_NUB_THREAD ((nub_thread_t)0)
#define INVALID_NUB_WATCH_ID ((nub_watch_t)0)
#define INVALID_NUB_HW_INDEX UINT32_MAX
#define INVALID_NUB_REGNUM UINT32_MAX
#define NUB_GENERIC_ERROR UINT32_MAX
// Watchpoint types
#define WATCH_TYPE_READ (1u << 0)
#define WATCH_TYPE_WRITE (1u << 1)
typedef enum {
eStateInvalid = 0,
eStateUnloaded,
eStateAttaching,
eStateLaunching,
eStateStopped,
eStateRunning,
eStateStepping,
eStateCrashed,
eStateDetached,
eStateExited,
eStateSuspended
} nub_state_t;
typedef enum {
eLaunchFlavorDefault = 0,
eLaunchFlavorPosixSpawn = 1,
eLaunchFlavorForkExec = 2,
#ifdef WITH_SPRINGBOARD
eLaunchFlavorSpringBoard = 3,
#endif
#ifdef WITH_BKS
eLaunchFlavorBKS = 4,
#endif
#ifdef WITH_FBS
eLaunchFlavorFBS = 5
#endif
} nub_launch_flavor_t;
#define NUB_STATE_IS_RUNNING(s) \
((s) == eStateAttaching || (s) == eStateLaunching || (s) == eStateRunning || \
(s) == eStateStepping || (s) == eStateDetached)
#define NUB_STATE_IS_STOPPED(s) \
((s) == eStateUnloaded || (s) == eStateStopped || (s) == eStateCrashed || \
(s) == eStateExited)
enum {
eEventProcessRunningStateChanged =
1 << 0, // The process has changed state to running
eEventProcessStoppedStateChanged =
1 << 1, // The process has changed state to stopped
eEventSharedLibsStateChange =
1 << 2, // Shared libraries loaded/unloaded state has changed
eEventStdioAvailable = 1 << 3, // Something is available on stdout/stderr
eEventProfileDataAvailable = 1 << 4, // Profile data ready for retrieval
kAllEventsMask = eEventProcessRunningStateChanged |
eEventProcessStoppedStateChanged |
eEventSharedLibsStateChange | eEventStdioAvailable |
eEventProfileDataAvailable
};
#define LOG_VERBOSE (1u << 0)
#define LOG_PROCESS (1u << 1)
#define LOG_THREAD (1u << 2)
#define LOG_EXCEPTIONS (1u << 3)
#define LOG_SHLIB (1u << 4)
#define LOG_MEMORY (1u << 5) // Log memory reads/writes calls
#define LOG_MEMORY_DATA_SHORT (1u << 6) // Log short memory reads/writes bytes
#define LOG_MEMORY_DATA_LONG (1u << 7) // Log all memory reads/writes bytes
#define LOG_MEMORY_PROTECTIONS (1u << 8) // Log memory protection changes
#define LOG_BREAKPOINTS (1u << 9)
#define LOG_EVENTS (1u << 10)
#define LOG_WATCHPOINTS (1u << 11)
#define LOG_STEP (1u << 12)
#define LOG_TASK (1u << 13)
#define LOG_DARWIN_LOG (1u << 14)
#define LOG_LO_USER (1u << 16)
#define LOG_HI_USER (1u << 31)
#define LOG_ALL 0xFFFFFFFFu
#define LOG_DEFAULT \
((LOG_PROCESS) | (LOG_TASK) | (LOG_THREAD) | (LOG_EXCEPTIONS) | \
(LOG_SHLIB) | (LOG_MEMORY) | (LOG_BREAKPOINTS) | (LOG_WATCHPOINTS) | \
(LOG_STEP))
#define REGISTER_SET_ALL 0
// Generic Register set to be defined by each architecture for access to common
// register values.
#define REGISTER_SET_GENERIC ((uint32_t)0xFFFFFFFFu)
#define GENERIC_REGNUM_PC 0 // Program Counter
#define GENERIC_REGNUM_SP 1 // Stack Pointer
#define GENERIC_REGNUM_FP 2 // Frame Pointer
#define GENERIC_REGNUM_RA 3 // Return Address
#define GENERIC_REGNUM_FLAGS 4 // Processor flags register
#define GENERIC_REGNUM_ARG1 \
5 // The register that would contain pointer size or less argument 1 (if any)
#define GENERIC_REGNUM_ARG2 \
6 // The register that would contain pointer size or less argument 2 (if any)
#define GENERIC_REGNUM_ARG3 \
7 // The register that would contain pointer size or less argument 3 (if any)
#define GENERIC_REGNUM_ARG4 \
8 // The register that would contain pointer size or less argument 4 (if any)
#define GENERIC_REGNUM_ARG5 \
9 // The register that would contain pointer size or less argument 5 (if any)
#define GENERIC_REGNUM_ARG6 \
10 // The register that would contain pointer size or less argument 6 (if any)
#define GENERIC_REGNUM_ARG7 \
11 // The register that would contain pointer size or less argument 7 (if any)
#define GENERIC_REGNUM_ARG8 \
12 // The register that would contain pointer size or less argument 8 (if any)
enum DNBRegisterType {
InvalidRegType = 0,
Uint, // unsigned integer
Sint, // signed integer
IEEE754, // float
Vector // vector registers
};
enum DNBRegisterFormat {
InvalidRegFormat = 0,
Binary,
Decimal,
Hex,
Float,
VectorOfSInt8,
VectorOfUInt8,
VectorOfSInt16,
VectorOfUInt16,
VectorOfSInt32,
VectorOfUInt32,
VectorOfFloat32,
VectorOfUInt128
};
struct DNBRegisterInfo {
uint32_t set; // Register set
uint32_t reg; // Register number
const char *name; // Name of this register
const char *alt; // Alternate name
uint16_t type; // Type of the register bits (DNBRegisterType)
uint16_t format; // Default format for display (DNBRegisterFormat),
uint32_t size; // Size in bytes of the register
uint32_t offset; // Offset from the beginning of the register context
uint32_t
reg_ehframe; // eh_frame register number (INVALID_NUB_REGNUM when none)
uint32_t reg_dwarf; // DWARF register number (INVALID_NUB_REGNUM when none)
uint32_t
reg_generic; // Generic register number (INVALID_NUB_REGNUM when none)
uint32_t reg_debugserver; // The debugserver register number we'll use over
// gdb-remote protocol (INVALID_NUB_REGNUM when
// none)
const char **value_regs; // If this register is a part of other registers,
// list the register names terminated by NULL
const char **update_regs; // If modifying this register will invalidate other
// registers, list the register names terminated by
// NULL
};
struct DNBRegisterSetInfo {
const char *name; // Name of this register set
const struct DNBRegisterInfo *registers; // An array of register descriptions
nub_size_t num_registers; // The number of registers in REGISTERS array above
};
struct DNBThreadResumeAction {
nub_thread_t tid; // The thread ID that this action applies to,
// INVALID_NUB_THREAD for the default thread action
nub_state_t state; // Valid values are eStateStopped/eStateSuspended,
// eStateRunning, and eStateStepping.
int signal; // When resuming this thread, resume it with this signal
nub_addr_t addr; // If not INVALID_NUB_ADDRESS, then set the PC for the thread
// to ADDR before resuming/stepping
};
enum DNBThreadStopType {
eStopTypeInvalid = 0,
eStopTypeSignal,
eStopTypeException,
eStopTypeExec
};
enum DNBMemoryPermissions {
eMemoryPermissionsWritable = (1 << 0),
eMemoryPermissionsReadable = (1 << 1),
eMemoryPermissionsExecutable = (1 << 2)
};
#define DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH 256
#define DNB_THREAD_STOP_INFO_MAX_EXC_DATA 8
//----------------------------------------------------------------------
// DNBThreadStopInfo
//
// Describes the reason a thread stopped.
//----------------------------------------------------------------------
struct DNBThreadStopInfo {
DNBThreadStopType reason;
char description[DNB_THREAD_STOP_INFO_MAX_DESC_LENGTH];
union {
// eStopTypeSignal
struct {
uint32_t signo;
} signal;
// eStopTypeException
struct {
uint32_t type;
nub_size_t data_count;
nub_addr_t data[DNB_THREAD_STOP_INFO_MAX_EXC_DATA];
} exception;
} details;
};
struct DNBRegisterValue {
struct DNBRegisterInfo info; // Register information for this register
union {
int8_t sint8;
int16_t sint16;
int32_t sint32;
int64_t sint64;
uint8_t uint8;
uint16_t uint16;
uint32_t uint32;
uint64_t uint64;
float float32;
double float64;
int8_t v_sint8[32];
int16_t v_sint16[16];
int32_t v_sint32[8];
int64_t v_sint64[4];
uint8_t v_uint8[32];
uint16_t v_uint16[16];
uint32_t v_uint32[8];
uint64_t v_uint64[4];
float v_float32[8];
double v_float64[4];
void *pointer;
char *c_str;
} value;
};
enum DNBSharedLibraryState { eShlibStateUnloaded = 0, eShlibStateLoaded = 1 };
#ifndef DNB_MAX_SEGMENT_NAME_LENGTH
#define DNB_MAX_SEGMENT_NAME_LENGTH 32
#endif
struct DNBSegment {
char name[DNB_MAX_SEGMENT_NAME_LENGTH];
nub_addr_t addr;
nub_addr_t size;
};
struct DNBExecutableImageInfo {
char name[PATH_MAX]; // Name of the executable image (usually a full path)
uint32_t
state; // State of the executable image (see enum DNBSharedLibraryState)
nub_addr_t header_addr; // Executable header address
uuid_t uuid; // Unique identifier for matching with symbols
uint32_t
num_segments; // Number of contiguous memory segments to in SEGMENTS array
DNBSegment *segments; // Array of contiguous memory segments in executable
};
struct DNBRegionInfo {
nub_addr_t addr;
nub_addr_t size;
uint32_t permissions;
};
enum DNBProfileDataScanType {
eProfileHostCPU = (1 << 0),
eProfileCPU = (1 << 1),
eProfileThreadsCPU =
(1 << 2), // By default excludes eProfileThreadName and eProfileQueueName.
eProfileThreadName =
(1 << 3), // Assume eProfileThreadsCPU, get thread name as well.
eProfileQueueName =
(1 << 4), // Assume eProfileThreadsCPU, get queue name as well.
eProfileHostMemory = (1 << 5),
eProfileMemory = (1 << 6), // By default, excludes eProfileMemoryDirtyPage.
eProfileMemoryDirtyPage =
(1 << 7), // Assume eProfileMemory, get Dirty Page size as well.
eProfileMemoryAnonymous =
(1 << 8), // Assume eProfileMemory, get Anonymous memory as well.
eProfileEnergy = (1 << 9),
eProfileAll = 0xffffffff
};
typedef nub_addr_t (*DNBCallbackNameToAddress)(nub_process_t pid,
const char *name,
const char *shlib_regex,
void *baton);
typedef nub_size_t (*DNBCallbackCopyExecutableImageInfos)(
nub_process_t pid, struct DNBExecutableImageInfo **image_infos,
nub_bool_t only_changed, void *baton);
typedef void (*DNBCallbackLog)(void *baton, uint32_t flags, const char *format,
va_list args);
#define UNUSED_IF_ASSERT_DISABLED(x) ((void)(x))
#endif // #ifndef __DNBDefs_h__

View File

@@ -0,0 +1,116 @@
//===-- DNBError.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 6/26/07.
//
//===----------------------------------------------------------------------===//
#include "DNBError.h"
#include "CFString.h"
#include "DNBLog.h"
#include "PThreadMutex.h"
#ifdef WITH_SPRINGBOARD
#include <SpringBoardServices/SpringBoardServer.h>
#endif
const char *DNBError::AsString() const {
if (Success())
return NULL;
if (m_str.empty()) {
const char *s = NULL;
switch (m_flavor) {
case MachKernel:
s = ::mach_error_string(m_err);
break;
case POSIX:
s = ::strerror(m_err);
break;
#ifdef WITH_SPRINGBOARD
case SpringBoard: {
CFStringRef statusStr = SBSApplicationLaunchingErrorString(m_err);
if (CFString::UTF8(statusStr, m_str) == NULL)
m_str.clear();
} break;
#endif
#ifdef WITH_BKS
case BackBoard: {
// You have to call ObjC routines to get the error string from
// BackBoardServices.
// Not sure I want to make DNBError.cpp an .mm file. For now just make
// sure you
// pre-populate the error string when you make the DNBError of type
// BackBoard.
m_str.assign(
"Should have set BackBoard error when making the error string.");
} break;
#endif
#ifdef WITH_FBS
case FrontBoard: {
// You have to call ObjC routines to get the error string from
// FrontBoardServices.
// Not sure I want to make DNBError.cpp an .mm file. For now just make
// sure you
// pre-populate the error string when you make the DNBError of type
// FrontBoard.
m_str.assign(
"Should have set FrontBoard error when making the error string.");
} break;
#endif
default:
break;
}
if (s)
m_str.assign(s);
}
if (m_str.empty())
return NULL;
return m_str.c_str();
}
void DNBError::LogThreadedIfError(const char *format, ...) const {
if (Fail()) {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
const char *err_str = AsString();
if (err_str == NULL)
err_str = "???";
DNBLogThreaded("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
free(arg_msg);
}
}
}
void DNBError::LogThreaded(const char *format, ...) const {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
if (Fail()) {
const char *err_str = AsString();
if (err_str == NULL)
err_str = "???";
DNBLogThreaded("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_err);
} else {
DNBLogThreaded("%s err = 0x%8.8x", arg_msg, m_err);
}
free(arg_msg);
}
}

View File

@@ -0,0 +1,98 @@
//===-- DNBError.h ----------------------------------------------*- 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 6/26/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBError_h__
#define __DNBError_h__
#include <errno.h>
#include <mach/mach.h>
#include <stdio.h>
#include <string>
class DNBError {
public:
typedef uint32_t ValueType;
typedef enum {
Generic = 0,
MachKernel = 1,
POSIX = 2
#ifdef WITH_SPRINGBOARD
,
SpringBoard = 3
#endif
#ifdef WITH_BKS
,
BackBoard = 4
#endif
#ifdef WITH_FBS
,
FrontBoard = 5
#endif
} FlavorType;
explicit DNBError(ValueType err = 0, FlavorType flavor = Generic)
: m_err(err), m_flavor(flavor) {}
const char *AsString() const;
void Clear() {
m_err = 0;
m_flavor = Generic;
m_str.clear();
}
ValueType Status() const { return m_err; }
FlavorType Flavor() const { return m_flavor; }
ValueType operator=(kern_return_t err) {
m_err = err;
m_flavor = MachKernel;
m_str.clear();
return m_err;
}
void SetError(kern_return_t err) {
m_err = err;
m_flavor = MachKernel;
m_str.clear();
}
void SetErrorToErrno() {
m_err = errno;
m_flavor = POSIX;
m_str.clear();
}
void SetError(ValueType err, FlavorType flavor) {
m_err = err;
m_flavor = flavor;
m_str.clear();
}
// Generic errors can set their own string values
void SetErrorString(const char *err_str) {
if (err_str && err_str[0])
m_str = err_str;
else
m_str.clear();
}
bool Success() const { return m_err == 0; }
bool Fail() const { return m_err != 0; }
void LogThreadedIfError(const char *format, ...) const;
void LogThreaded(const char *format, ...) const;
protected:
ValueType m_err;
FlavorType m_flavor;
mutable std::string m_str;
};
#endif // #ifndef __DNBError_h__

View File

@@ -0,0 +1,287 @@
//===-- DNBLog.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 6/18/07.
//
//===----------------------------------------------------------------------===//
#include "DNBLog.h"
static int g_debug = 0;
static int g_verbose = 0;
#if defined(DNBLOG_ENABLED)
#include "PThreadMutex.h"
#include <mach/mach.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
uint32_t g_log_bits = 0;
static DNBCallbackLog g_log_callback = NULL;
static void *g_log_baton = NULL;
int DNBLogGetDebug() { return g_debug; }
void DNBLogSetDebug(int g) { g_debug = g; }
int DNBLogGetVerbose() { return g_verbose; }
void DNBLogSetVerbose(int v) { g_verbose = v; }
bool DNBLogCheckLogBit(uint32_t bit) { return (g_log_bits & bit) != 0; }
uint32_t DNBLogSetLogMask(uint32_t mask) {
uint32_t old = g_log_bits;
g_log_bits = mask;
return old;
}
uint32_t DNBLogGetLogMask() { return g_log_bits; }
void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton) {
g_log_callback = callback;
g_log_baton = baton;
}
DNBCallbackLog DNBLogGetLogCallback() { return g_log_callback; }
bool DNBLogEnabled() { return g_log_callback != NULL; }
bool DNBLogEnabledForAny(uint32_t mask) {
if (g_log_callback)
return (g_log_bits & mask) != 0;
return false;
}
static inline void _DNBLogVAPrintf(uint32_t flags, const char *format,
va_list args) {
static PThreadMutex g_LogThreadedMutex(PTHREAD_MUTEX_RECURSIVE);
PTHREAD_MUTEX_LOCKER(locker, g_LogThreadedMutex);
if (g_log_callback)
g_log_callback(g_log_baton, flags, format, args);
}
void _DNBLog(uint32_t flags, const char *format, ...) {
va_list args;
va_start(args, format);
_DNBLogVAPrintf(flags, format, args);
va_end(args);
}
//----------------------------------------------------------------------
// Print debug strings if and only if the global g_debug is set to
// a non-zero value.
//----------------------------------------------------------------------
void _DNBLogDebug(const char *format, ...) {
if (DNBLogEnabled() && g_debug) {
va_list args;
va_start(args, format);
_DNBLogVAPrintf(DNBLOG_FLAG_DEBUG, format, args);
va_end(args);
}
}
//----------------------------------------------------------------------
// Print debug strings if and only if the global g_debug is set to
// a non-zero value.
//----------------------------------------------------------------------
void _DNBLogDebugVerbose(const char *format, ...) {
if (DNBLogEnabled() && g_debug && g_verbose) {
va_list args;
va_start(args, format);
_DNBLogVAPrintf(DNBLOG_FLAG_DEBUG | DNBLOG_FLAG_VERBOSE, format, args);
va_end(args);
}
}
static uint32_t g_message_id = 0;
//----------------------------------------------------------------------
// Prefix the formatted log string with process and thread IDs and
// suffix it with a newline.
//----------------------------------------------------------------------
void _DNBLogThreaded(const char *format, ...) {
if (DNBLogEnabled()) {
// PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
static struct timeval g_timeval = {0, 0};
static struct timeval tv;
static struct timeval delta;
gettimeofday(&tv, NULL);
if (g_timeval.tv_sec == 0) {
delta.tv_sec = 0;
delta.tv_usec = 0;
} else {
timersub(&tv, &g_timeval, &delta);
}
g_timeval = tv;
// Calling "mach_port_deallocate()" bumps the reference count on the
// thread
// port, so we need to deallocate it. mach_task_self() doesn't bump the
// ref
// count.
thread_port_t thread_self = mach_thread_self();
_DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
thread_self, arg_msg);
mach_port_deallocate(mach_task_self(), thread_self);
free(arg_msg);
}
}
}
//----------------------------------------------------------------------
// Prefix the formatted log string with process and thread IDs and
// suffix it with a newline.
//----------------------------------------------------------------------
void _DNBLogThreadedIf(uint32_t log_bit, const char *format, ...) {
if (DNBLogEnabled() && (log_bit & g_log_bits) == log_bit) {
// PTHREAD_MUTEX_LOCKER(locker, GetLogThreadedMutex());
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
static struct timeval g_timeval = {0, 0};
static struct timeval tv;
static struct timeval delta;
gettimeofday(&tv, NULL);
if (g_timeval.tv_sec == 0) {
delta.tv_sec = 0;
delta.tv_usec = 0;
} else {
timersub(&tv, &g_timeval, &delta);
}
g_timeval = tv;
// Calling "mach_port_deallocate()" bumps the reference count on the
// thread
// port, so we need to deallocate it. mach_task_self() doesn't bump the
// ref
// count.
thread_port_t thread_self = mach_thread_self();
_DNBLog(DNBLOG_FLAG_THREADED, "%u +%lu.%06u sec [%4.4x/%4.4x]: %s",
++g_message_id, delta.tv_sec, delta.tv_usec, getpid(),
thread_self, arg_msg);
mach_port_deallocate(mach_task_self(), thread_self);
free(arg_msg);
}
}
}
//----------------------------------------------------------------------
// Printing of errors that are not fatal.
//----------------------------------------------------------------------
void _DNBLogError(const char *format, ...) {
if (DNBLogEnabled()) {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
_DNBLog(DNBLOG_FLAG_ERROR, "error: %s", arg_msg);
free(arg_msg);
}
}
}
//----------------------------------------------------------------------
// Printing of errors that ARE fatal. Exit with ERR exit code
// immediately.
//----------------------------------------------------------------------
void _DNBLogFatalError(int err, const char *format, ...) {
if (DNBLogEnabled()) {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
_DNBLog(DNBLOG_FLAG_ERROR | DNBLOG_FLAG_FATAL, "error: %s", arg_msg);
free(arg_msg);
}
::exit(err);
}
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
//----------------------------------------------------------------------
void _DNBLogVerbose(const char *format, ...) {
if (DNBLogEnabled() && g_verbose) {
va_list args;
va_start(args, format);
_DNBLogVAPrintf(DNBLOG_FLAG_VERBOSE, format, args);
va_end(args);
}
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
//----------------------------------------------------------------------
void _DNBLogWarningVerbose(const char *format, ...) {
if (DNBLogEnabled() && g_verbose) {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
_DNBLog(DNBLOG_FLAG_WARNING | DNBLOG_FLAG_VERBOSE, "warning: %s",
arg_msg);
free(arg_msg);
}
}
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal.
//----------------------------------------------------------------------
void _DNBLogWarning(const char *format, ...) {
if (DNBLogEnabled()) {
char *arg_msg = NULL;
va_list args;
va_start(args, format);
::vasprintf(&arg_msg, format, args);
va_end(args);
if (arg_msg != NULL) {
_DNBLog(DNBLOG_FLAG_WARNING, "warning: %s", arg_msg);
free(arg_msg);
}
}
}
#endif

View File

@@ -0,0 +1,153 @@
//===-- DNBLog.h ------------------------------------------------*- 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 6/18/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBLog_h__
#define __DNBLog_h__
#include "DNBDefs.h"
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
// Flags that get filled in automatically before calling the log callback
// function
#define DNBLOG_FLAG_FATAL (1u << 0)
#define DNBLOG_FLAG_ERROR (1u << 1)
#define DNBLOG_FLAG_WARNING (1u << 2)
#define DNBLOG_FLAG_DEBUG (1u << 3)
#define DNBLOG_FLAG_VERBOSE (1u << 4)
#define DNBLOG_FLAG_THREADED (1u << 5)
#define DNBLOG_ENABLED
#if defined(DNBLOG_ENABLED)
void _DNBLog(uint32_t flags, const char *format, ...)
__attribute__((format(printf, 2, 3)));
void _DNBLogDebug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void _DNBLogDebugVerbose(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void _DNBLogThreaded(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
void _DNBLogThreadedIf(uint32_t mask, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
void _DNBLogError(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void _DNBLogFatalError(int err, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
void _DNBLogVerbose(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void _DNBLogWarning(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
void _DNBLogWarningVerbose(const char *fmt, ...)
__attribute__((format(printf, 1, 2)));
bool DNBLogCheckLogBit(uint32_t bit);
uint32_t DNBLogSetLogMask(uint32_t mask);
uint32_t DNBLogGetLogMask();
void DNBLogSetLogCallback(DNBCallbackLog callback, void *baton);
DNBCallbackLog DNBLogGetLogCallback();
bool DNBLogEnabled();
bool DNBLogEnabledForAny(uint32_t mask);
int DNBLogGetDebug();
void DNBLogSetDebug(int g);
int DNBLogGetVerbose();
void DNBLogSetVerbose(int g);
#define DNBLog(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLog(0, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogDebug(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogDebug(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogDebugVerbose(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogDebugVerbose(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogThreaded(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogThreaded(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogThreadedIf(mask, fmt, ...) \
do { \
if (DNBLogEnabledForAny(mask)) { \
_DNBLogThreaded(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogError(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogError(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogFatalError(err, fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogFatalError(err, fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogVerbose(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogVerbose(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogWarning(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogWarning(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define DNBLogWarningVerbose(fmt, ...) \
do { \
if (DNBLogEnabled()) { \
_DNBLogWarningVerbose(fmt, ##__VA_ARGS__); \
} \
} while (0)
#else // #if defined(DNBLOG_ENABLED)
#define DNBLogDebug(...) ((void)0)
#define DNBLogDebugVerbose(...) ((void)0)
#define DNBLogThreaded(...) ((void)0)
#define DNBLogThreadedIf(...) ((void)0)
#define DNBLogError(...) ((void)0)
#define DNBLogFatalError(...) ((void)0)
#define DNBLogVerbose(...) ((void)0)
#define DNBLogWarning(...) ((void)0)
#define DNBLogWarningVerbose(...) ((void)0)
#define DNBLogGetLogFile() ((FILE *)NULL)
#define DNBLogSetLogFile(f) ((void)0)
#define DNBLogCheckLogBit(bit) ((bool)false)
#define DNBLogSetLogMask(mask) ((uint32_t)0u)
#define DNBLogGetLogMask() ((uint32_t)0u)
#define DNBLogToASL() ((void)0)
#define DNBLogToFile() ((void)0)
#define DNBLogCloseLogFile() ((void)0)
#endif // #else defined(DNBLOG_ENABLED)
#ifdef __cplusplus
}
#endif
#endif // #ifndef __DNBLog_h__

View File

@@ -0,0 +1,251 @@
//===-- DNBRegisterInfo.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 8/3/07.
//
//===----------------------------------------------------------------------===//
#include "DNBRegisterInfo.h"
#include "DNBLog.h"
#include <string.h>
DNBRegisterValueClass::DNBRegisterValueClass(const DNBRegisterInfo *regInfo) {
Clear();
if (regInfo)
info = *regInfo;
}
void DNBRegisterValueClass::Clear() {
memset(&info, 0, sizeof(DNBRegisterInfo));
memset(&value, 0, sizeof(value));
}
bool DNBRegisterValueClass::IsValid() const {
return info.name != NULL && info.type != InvalidRegType && info.size > 0 &&
info.size <= sizeof(value);
}
#define PRINT_COMMA_SEPARATOR \
do { \
if (pos < end) { \
if (i > 0) { \
strlcpy(pos, ", ", end - pos); \
pos += 2; \
} \
} \
} while (0)
void DNBRegisterValueClass::Dump(const char *pre, const char *post) const {
if (info.name != NULL) {
char str[1024];
char *pos;
char *end = str + sizeof(str);
if (info.format == Hex) {
switch (info.size) {
case 0:
snprintf(str, sizeof(str), "%s",
"error: invalid register size of zero.");
break;
case 1:
snprintf(str, sizeof(str), "0x%2.2x", value.uint8);
break;
case 2:
snprintf(str, sizeof(str), "0x%4.4x", value.uint16);
break;
case 4:
snprintf(str, sizeof(str), "0x%8.8x", value.uint32);
break;
case 8:
snprintf(str, sizeof(str), "0x%16.16llx", value.uint64);
break;
case 16:
snprintf(str, sizeof(str), "0x%16.16llx%16.16llx", value.v_uint64[0],
value.v_uint64[1]);
break;
default:
strlcpy(str, "0x", 3);
pos = str + 2;
for (uint32_t i = 0; i < info.size; ++i) {
if (pos < end)
pos +=
snprintf(pos, end - pos, "%2.2x", (uint32_t)value.v_uint8[i]);
}
break;
}
} else {
switch (info.type) {
case Uint:
switch (info.size) {
case 1:
snprintf(str, sizeof(str), "%u", value.uint8);
break;
case 2:
snprintf(str, sizeof(str), "%u", value.uint16);
break;
case 4:
snprintf(str, sizeof(str), "%u", value.uint32);
break;
case 8:
snprintf(str, sizeof(str), "%llu", value.uint64);
break;
default:
snprintf(str, sizeof(str), "error: unsupported uint byte size %d.",
info.size);
break;
}
break;
case Sint:
switch (info.size) {
case 1:
snprintf(str, sizeof(str), "%d", value.sint8);
break;
case 2:
snprintf(str, sizeof(str), "%d", value.sint16);
break;
case 4:
snprintf(str, sizeof(str), "%d", value.sint32);
break;
case 8:
snprintf(str, sizeof(str), "%lld", value.sint64);
break;
default:
snprintf(str, sizeof(str), "error: unsupported sint byte size %d.",
info.size);
break;
}
break;
case IEEE754:
switch (info.size) {
case 4:
snprintf(str, sizeof(str), "%f", value.float32);
break;
case 8:
snprintf(str, sizeof(str), "%g", value.float64);
break;
default:
snprintf(str, sizeof(str), "error: unsupported float byte size %d.",
info.size);
break;
}
break;
case Vector:
if (info.size > 0) {
switch (info.format) {
case VectorOfSInt8:
snprintf(str, sizeof(str), "%s", "sint8 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%d", (int32_t)value.v_sint8[i]);
}
strlcat(str, " }", sizeof(str));
break;
default:
DNBLogError(
"unsupported vector format %d, defaulting to hex bytes.",
info.format);
case VectorOfUInt8:
snprintf(str, sizeof(str), "%s", "uint8 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint8[i]);
}
break;
case VectorOfSInt16:
snprintf(str, sizeof(str), "%s", "sint16 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 2; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%d", (int32_t)value.v_sint16[i]);
}
break;
case VectorOfUInt16:
snprintf(str, sizeof(str), "%s", "uint16 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 2; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint16[i]);
}
break;
case VectorOfSInt32:
snprintf(str, sizeof(str), "%s", "sint32 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 4; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%d", (int32_t)value.v_sint32[i]);
}
break;
case VectorOfUInt32:
snprintf(str, sizeof(str), "%s", "uint32 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 4; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos +=
snprintf(pos, end - pos, "%u", (uint32_t)value.v_uint32[i]);
}
break;
case VectorOfFloat32:
snprintf(str, sizeof(str), "%s", "float32 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 4; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos += snprintf(pos, end - pos, "%f", value.v_float32[i]);
}
break;
case VectorOfUInt128:
snprintf(str, sizeof(str), "%s", "uint128 { ");
pos = str + strlen(str);
for (uint32_t i = 0; i < info.size / 16; ++i) {
PRINT_COMMA_SEPARATOR;
if (pos < end)
pos += snprintf(pos, end - pos, "0x%16.16llx%16.16llx",
value.v_uint64[i], value.v_uint64[i + 1]);
}
break;
}
strlcat(str, " }", sizeof(str));
} else {
snprintf(str, sizeof(str), "error: unsupported vector size %d.",
info.size);
}
break;
default:
snprintf(str, sizeof(str), "error: unsupported register type %d.",
info.type);
break;
}
}
DNBLog("%s%4s = %s%s", pre ? pre : "", info.name, str, post ? post : "");
}
}

View File

@@ -0,0 +1,30 @@
//===-- DNBRegisterInfo.h ---------------------------------------*- 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 8/3/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBRegisterInfo_h__
#define __DNBRegisterInfo_h__
#include "DNBDefs.h"
#include <stdint.h>
#include <stdio.h>
struct DNBRegisterValueClass : public DNBRegisterValue {
#ifdef __cplusplus
DNBRegisterValueClass(const DNBRegisterInfo *regInfo = NULL);
void Clear();
void Dump(const char *pre, const char *post) const;
bool IsValid() const;
#endif
};
#endif

View File

@@ -0,0 +1,24 @@
//===-- DNBRuntimeAction.h --------------------------------------*- 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/07.
//
//===----------------------------------------------------------------------===//
#ifndef __DNBRuntimeAction_h__
#define __DNBRuntimeAction_h__
class DNBRuntimeAction {
virtual void Initialize(nub_process_t pid) = 0;
virtual void ProcessStateChanged(nub_state_t state) = 0;
virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos,
nub_size_t num_image_infos) = 0;
};
#endif // #ifndef __DNBRuntimeAction_h__

Some files were not shown because too many files have changed in this diff Show More