]> Chaos Git - corbenik/ctrulib.git/commitdiff
Finish implementing the debug SVCs and associated types
authorTuxSH <tuxsh@sfr.fr>
Wed, 21 Dec 2016 21:20:02 +0000 (22:20 +0100)
committerTuxSH <tuxsh@sfr.fr>
Fri, 23 Dec 2016 13:57:32 +0000 (14:57 +0100)
libctru/include/3ds/errf.h
libctru/include/3ds/svc.h
libctru/include/3ds/types.h
libctru/source/svc.s

index 70123a9981d7f7fa223ed6823333ff40254df788..f1acd928da92c0ce9ae6e2dda9dbfc8075d87a6d 100644 (file)
@@ -7,11 +7,6 @@
 
 #include <3ds/types.h>
 
-/// Used for register dumps.
-typedef struct {
-       u32 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, cpsr;
-} ERRF_ExceptionContext;
-
 /// Types of errors that can be thrown by err:f.
 typedef enum {
        ERRF_ERRTYPE_GENERIC      = 0, ///< For generic errors. Shows miscellaneous info.
@@ -19,7 +14,7 @@ typedef enum {
        ERRF_ERRTYPE_CARD_REMOVED = 2, ///< Displays the "The Game Card was removed." message.
        ERRF_ERRTYPE_EXCEPTION    = 3, ///< For exceptions, or more specifically 'crashes'. union data should be exception_data.
        ERRF_ERRTYPE_FAILURE      = 4, ///< For general failure. Shows a message. union data should have a string set in failure_mesg
-       ERRF_ERRTYPE_LOGGED       = 5  ///< Outputs logs to NAND in some cases.
+       ERRF_ERRTYPE_LOGGED       = 5, ///< Outputs logs to NAND in some cases.
 } ERRF_ErrType;
 
 /// Types of 'Exceptions' thrown for ERRF_ERRTYPE_EXCEPTION
@@ -27,7 +22,7 @@ typedef enum {
        ERRF_EXCEPTION_PREFETCH_ABORT = 0, ///< Prefetch Abort
        ERRF_EXCEPTION_DATA_ABORT     = 1, ///< Data abort
        ERRF_EXCEPTION_UNDEFINED      = 2, ///< Undefined instruction
-       ERRF_EXCEPTION_VFP            = 3  ///< VFP (floating point) exception.
+       ERRF_EXCEPTION_VFP            = 3, ///< VFP (floating point) exception.
 } ERRF_ExceptionType;
 
 typedef struct {
@@ -42,7 +37,7 @@ typedef struct {
 
 typedef struct {
        ERRF_ExceptionInfo excep;   ///< Exception info struct
-       ERRF_ExceptionContext regs; ///< Register dump.
+       CpuRegisters regs;          ///< CPU register dump.
        u8 pad[4];
 } ERRF_ExceptionData;
 
index 7b2a5241105612e5860f9a00409d17063095bade..bf1d708f772d740cac19f40f9f21f872cc79983c 100644 (file)
@@ -49,15 +49,15 @@ typedef enum {
        MEMSTATE_ALIASED    = 8,  ///< Aliased memory
        MEMSTATE_ALIAS      = 9,  ///< Alias memory
        MEMSTATE_ALIASCODE  = 10, ///< Aliased code memory
-       MEMSTATE_LOCKED     = 11  ///< Locked memory
+       MEMSTATE_LOCKED     = 11, ///< Locked memory
 } MemState;
 
 /// Memory permission flags
 typedef enum {
-       MEMPERM_READ     = 1,         ///< Readable
-       MEMPERM_WRITE    = 2,         ///< Writable
-       MEMPERM_EXECUTE  = 4,         ///< Executable
-       MEMPERM_DONTCARE = 0x10000000 ///< Don't care
+       MEMPERM_READ     = 1,          ///< Readable
+       MEMPERM_WRITE    = 2,          ///< Writable
+       MEMPERM_EXECUTE  = 4,          ///< Executable
+       MEMPERM_DONTCARE = 0x10000000, ///< Don't care
 } MemPerm;
 
 /// Memory information.
@@ -103,7 +103,7 @@ typedef enum {
 } ThreadInfoType;
 
 /// Pseudo handle for the current thread
-#define CUR_THREAD_HANDLE 0xFFFF8000
+#define CUR_THREAD_HANDLE  0xFFFF8000
 
 ///@}
 
@@ -111,83 +111,114 @@ typedef enum {
 ///@name Debugging
 ///@{
 
-/// Reasons for a process event.
-typedef enum {
-       REASON_CREATE = 1, ///< Process created.
-       REASON_ATTACH = 2  ///< Process attached.
-} ProcessEventReason;
-
-/// Event relating to a process.
+/// Event relating to the attachment of a process.
 typedef struct {
-       u64 program_id;      ///< ID of the program.
-       u8  process_name[8]; ///< Name of the process.
-       u32 process_id;      ///< ID of the process.
-       u32 reason;          ///< Reason for the event. See @ref ProcessEventReason
-} ProcessEvent;
+       u64 program_id;       ///< ID of the program.
+       char process_name[8]; ///< Name of the process.
+       u32 process_id;       ///< ID of the process.
+       u32 other_flags;      ///< Always 0
+} AttachProcessEvent;
 
 /// Reasons for an exit process event.
 typedef enum {
        EXITPROCESS_EVENT_NONE                = 0, ///< No reason.
        EXITPROCESS_EVENT_TERMINATE           = 1, ///< Process terminated.
-       EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2  ///< Unhandled exception occurred.
+       EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2, ///< Unhandled exception occurred.
 } ExitProcessEventReason;
 
 /// Event relating to the exiting of a process.
 typedef struct {
-       u32 reason; ///< Reason for exiting. See @ref ExitProcessEventReason
+       ExitProcessEventReason reason; ///< Reason for exiting. See @ref ExitProcessEventReason
 } ExitProcessEvent;
 
-/// Event relating to the creation of a thread.
+/// Event relating to the attachment of a thread.
 typedef struct {
-       u32 creator_thread_id; ///< ID of the creating thread.
-       u32 base_addr;         ///< Base address.
-       u32 entry_point;       ///< Entry point of the thread.
-} CreateThreadEvent;
+       u32 creator_thread_id;    ///< ID of the creating thread.
+       u32 thread_local_storage; ///< Thread local storage.
+       u32 entry_point;          ///< Entry point of the thread.
+} AttachThreadEvent;
 
 /// Reasons for an exit thread event.
 typedef enum {
        EXITTHREAD_EVENT_NONE              = 0, ///< No reason.
        EXITTHREAD_EVENT_TERMINATE         = 1, ///< Thread terminated.
        EXITTHREAD_EVENT_UNHANDLED_EXC     = 2, ///< Unhandled exception occurred.
-       EXITTHREAD_EVENT_TERMINATE_PROCESS = 3  ///< Process terminated.
+       EXITTHREAD_EVENT_TERMINATE_PROCESS = 3, ///< Process terminated.
 } ExitThreadEventReason;
 
 /// Event relating to the exiting of a thread.
 typedef struct {
-       u32 reason; ///< Reason for exiting. See @ref ExitThreadEventReason
+       ExitThreadEventReason reason; ///< Reason for exiting. See @ref ExitThreadEventReason
 } ExitThreadEvent;
 
 /// Reasons for a user break.
 typedef enum {
-       USERBREAK_PANIC  = 0, ///< Panic.
-       USERBREAK_ASSERT = 1, ///< Assertion failed.
-       USERBREAK_USER   = 2  ///< User related.
+       USERBREAK_PANIC         = 0, ///< Panic.
+       USERBREAK_ASSERT        = 1, ///< Assertion failed.
+       USERBREAK_USER          = 2, ///< User related.
+       USERBREAK_LOAD_RO       = 3, ///< Load RO.
+       USERBREAK_UNLOAD_RO     = 4, ///< Unload RO.
 } UserBreakType;
 
 /// Reasons for an exception event.
 typedef enum {
-       EXC_EVENT_UNDEFINED_INSTRUCTION = 0, ///< Undefined instruction.   arg: (None)
-       EXC_EVENT_UNKNOWN1              = 1, ///< Unknown.                 arg: (None)
-       EXC_EVENT_UNKNOWN2              = 2, ///< Unknown.                 arg: address
-       EXC_EVENT_UNKNOWN3              = 3, ///< Unknown.                 arg: address
-       EXC_EVENT_ATTACH_BREAK          = 4, ///< Attached break.          arg: (None)
-       EXC_EVENT_BREAKPOINT            = 5, ///< Breakpoint reached.      arg: (None)
-       EXC_EVENT_USER_BREAK            = 6, ///< User break occurred.     arg: @ref UserBreakType
-       EXC_EVENT_DEBUGGER_BREAK        = 7, ///< Debugger break occurred. arg: (None)
-       EXC_EVENT_UNDEFINED_SYSCALL     = 8  ///< Undefined syscall.       arg: attempted syscall
+       EXCEVENT_UNDEFINED_INSTRUCTION = 0, ///< Undefined instruction.
+       EXCEVENT_PREFETCH_ABORT        = 1, ///< Prefetch abort.
+       EXCEVENT_DATA_ABORT            = 2, ///< Data abort (other than the below kind).
+       EXCEVENT_UNALIGNED_DATA_ACCESS = 3, ///< Unaligned data access.
+       EXCEVENT_ATTACH_BREAK          = 4, ///< Attached break.
+       EXCEVENT_STOP_POINT            = 5, ///< Stop point reached.
+       EXCEVENT_USER_BREAK            = 6, ///< User break occurred.
+       EXCEVENT_DEBUGGER_BREAK        = 7, ///< Debugger break occurred.
+       EXCEVENT_UNDEFINED_SYSCALL     = 8, ///< Undefined syscall.
 } ExceptionEventType;
 
+/// Event relating to fault exceptions (CPU exceptions other than stop points and undefined syscalls).
+typedef struct {
+       u32 fault_information; ///< FAR (for DATA ABORT / UNALIGNED DATA ACCESS), attempted syscall or 0
+} FaultExceptionEvent;
+
+/// Stop point types
+typedef enum {
+       STOPPOINT_SVC_FF        = 0, ///< See @ref SVC_STOP_POINT.
+       STOPPOINT_BREAKPOINT    = 1, ///< Breakpoint.
+       STOPPOINT_WATCHPOINT    = 2, ///< Watchpoint.
+} StopPointType;
+
+/// Event relating to stop points
+typedef struct {
+       StopPointType type;    ///< Stop point type, see @ref StopPointType.
+       u32 fault_information; ///< FAR for Watchpoints, otherwise 0.
+} StopPointExceptionEvent;
+
+/// Event relating to @ref svcBreak
+typedef struct {
+       UserBreakType type;   ///< User break type, see @ref UserBreakType.
+       u32 croInfo;          ///< For LOAD_RO and UNLOAD_RO.
+       u32 croInfoSize;      ///< For LOAD_RO and UNLOAD_RO.
+} UserBreakExceptionEvent;
+
+/// Event relating to @ref svcBreakDebugProcess
+typedef struct {
+       void *threads[4]; ///< KThread instances of the attached process's that were running on each at the time of the function call (only the first 2 values are meaningful on O3DS).
+} DebuggerBreakExceptionEvent;
+
 /// Event relating to exceptions.
 typedef struct {
-       u32 type;     ///< Type of event. See @ref ExceptionEventType
-       u32 address;  ///< Address of the exception.
-       u32 argument; ///< Event argument. See @ref ExceptionEventType
+       ExceptionEventType type; ///< Type of event. See @ref ExceptionEventType.
+       u32 address;             ///< Address of the exception.
+       union {
+               FaultExceptionEvent fault;                  ///< Fault exception event data.
+               StopPointExceptionEvent stop_point;         ///< Stop point exception event data.
+               UserBreakExceptionEvent user_break;         ///< User break exception event data.
+               DebuggerBreakExceptionEvent debugger_break; ///< Debugger break exception event data
+       };
 } ExceptionEvent;
 
 /// Event relating to the scheduler.
 typedef struct {
        u64 clock_tick; ///< Clock tick that the event occurred.
-} SchedulerInOutEvent;
+} ScheduleInOutEvent;
 
 /// Event relating to syscalls.
 typedef struct {
@@ -203,49 +234,84 @@ typedef struct {
 
 /// Event relating to the mapping of memory.
 typedef struct {
-       u32 mapped_addr; ///< Mapped address.
-       u32 mapped_size; ///< Mapped size.
-       u32 memperm;     ///< Memory permissions. See @ref MemPerm
-       u32 memstate;    ///< Memory state. See @ref MemState
+       u32 mapped_addr;   ///< Mapped address.
+       u32 mapped_size;   ///< Mapped size.
+       MemPerm memperm;   ///< Memory permissions. See @ref MemPerm.
+       MemState memstate; ///< Memory state. See @ref MemState.
 } MapEvent;
 
 /// Debug event type.
 typedef enum {
-       DBG_EVENT_PROCESS        = 0,  ///< Process event.
-       DBG_EVENT_CREATE_THREAD  = 1,  ///< Thread creation event.
-       DBG_EVENT_EXIT_THREAD    = 2,  ///< Thread exit event.
-       DBG_EVENT_EXIT_PROCESS   = 3,  ///< Process exit event.
-       DBG_EVENT_EXCEPTION      = 4,  ///< Exception event.
-       DBG_EVENT_DLL_LOAD       = 5,  ///< DLL load event.
-       DBG_EVENT_DLL_UNLOAD     = 6,  ///< DLL unload event.
-       DBG_EVENT_SCHEDULE_IN    = 7,  ///< Schedule in event.
-       DBG_EVENT_SCHEDULE_OUT   = 8,  ///< Schedule out event.
-       DBG_EVENT_SYSCALL_IN     = 9,  ///< Syscall in event.
-       DBG_EVENT_SYSCALL_OUT    = 10, ///< Syscall out event.
-       DBG_EVENT_OUTPUT_STRING  = 11, ///< Output string event.
-       DBG_EVENT_MAP            = 12  ///< Map event.
+       DBGEVENT_ATTACH_PROCESS = 0,  ///< Process attached event.
+       DBGEVENT_ATTACH_THREAD  = 1,  ///< Thread attached event.
+       DBGEVENT_EXIT_THREAD    = 2,  ///< Thread exit event.
+       DBGEVENT_EXIT_PROCESS   = 3,  ///< Process exit event.
+       DBGEVENT_EXCEPTION      = 4,  ///< Exception event.
+       DBGEVENT_DLL_LOAD       = 5,  ///< DLL load event.
+       DBGEVENT_DLL_UNLOAD     = 6,  ///< DLL unload event.
+       DBGEVENT_SCHEDULE_IN    = 7,  ///< Schedule in event.
+       DBGEVENT_SCHEDULE_OUT   = 8,  ///< Schedule out event.
+       DBGEVENT_SYSCALL_IN     = 9,  ///< Syscall in event.
+       DBGEVENT_SYSCALL_OUT    = 10, ///< Syscall out event.
+       DBGEVENT_OUTPUT_STRING  = 11, ///< Output string event.
+       DBGEVENT_MAP            = 12, ///< Map event.
 } DebugEventType;
 
 /// Information about a debug event.
 typedef struct {
-       u32 type;       ///< Type of event. See @ref DebugEventType
-       u32 thread_id;  ///< ID of the thread.
-       u32 unknown[2]; ///< Unknown data.
+       DebugEventType type; ///< Type of event. See @ref DebugEventType
+       u32 thread_id;       ///< ID of the thread.
+       u32 flags;           ///< Flags. Bit0 means that @ref svcContinueDebugEvent needs to be called for this event (except for EXIT PROCESS events, where this flag is disregarded).
+       u8 remnants[4];      ///< Always 0.
        union {
-               ProcessEvent process;            ///< Process event data.
-               CreateThreadEvent create_thread; ///< Thread creation event data.
-               ExitThreadEvent exit_thread;     ///< Thread exit event data.
-               ExitProcessEvent exit_process;   ///< Process exit event data.
-               ExceptionEvent exception;        ///< Exception event data.
-               /* TODO: DLL_LOAD */
-               /* TODO: DLL_UNLOAD */
-               SchedulerInOutEvent scheduler;   ///< Schedule in/out event data.
-               SyscallInOutEvent syscall;       ///< Syscall in/out event data.
-               OutputStringEvent output_string; ///< Output string event data.
-               MapEvent map;                    ///< Map event data.
+               AttachProcessEvent attach_process; ///< Process attachment event data.
+               AttachThreadEvent attach_thread;   ///< Thread attachment event data.
+               ExitThreadEvent exit_thread;       ///< Thread exit event data.
+               ExitProcessEvent exit_process;     ///< Process exit event data.
+               ExceptionEvent exception;          ///< Exception event data.
+               /* DLL_LOAD and DLL_UNLOAD do not seem to possess any event data */
+               ScheduleInOutEvent scheduler;      ///< Schedule in/out event data.
+               SyscallInOutEvent syscall;         ///< Syscall in/out event data.
+               OutputStringEvent output_string;   ///< Output string event data.
+               MapEvent map;                      ///< Map event data.
        };
 } DebugEventInfo;
 
+/// Debug flags for an attached process, set by @ref svcContinueDebugEvent
+typedef enum {
+       DBG_NO_ERRF_CPU_EXCEPTION_DUMPS   = BIT(0), ///< Don't produce err:f-format dumps for CPU exceptions (including watchpoints and breakpoints, regardless of any @ref svcKernelSetState call).
+       DBG_SIGNAL_FAULT_EXCEPTION_EVENTS = BIT(1), ///< Signal fault exception events. See @ref FaultExceptionEvent.
+       DBG_SIGNAL_SCHEDULE_EVENTS        = BIT(2), ///< Signal schedule in/out events. See @ref ScheduleInOutEvent.
+       DBG_SIGNAL_SYSCALL_EVENTS         = BIT(3), ///< Signal syscall in/out events. See @ref SyscallInOutEvent.
+       DBG_SIGNAL_MAP_EVENTS             = BIT(4), ///< Signal map events. See @ref MapEvent.
+} DebugFlags;
+
+typedef struct {
+       CpuRegisters cpu_registers; ///< CPU registers.
+       FpuRegisters fpu_registers; ///< FPU registers.
+} ThreadContext;
+
+/// Control flags for @ref svcGetDebugThreadContext and @ref svcSetDebugThreadContext
+typedef enum {
+       THREADCONTEXT_CONTROL_CPU_GPRS  = BIT(0), ///< Control r0-r12.
+       THREADCONTEXT_CONTROL_CPU_SPRS  = BIT(1), ///< Control sp, lr, pc, cpsr.
+       THREADCONTEXT_CONTROL_FPU_GPRS  = BIT(2), ///< Control d0-d15 (or f0-f31).
+       THREADCONTEXT_CONTROL_FPU_SPRS  = BIT(3), ///< Control fpscr, fpexc.
+
+       THREADCONTEXT_CONTROL_CPU_REGS  = BIT(0) | BIT(1), ///< Control r0-r12, sp, lr, pc, cpsr.
+       THREADCONTEXT_CONTROL_FPU_REGS  = BIT(2) | BIT(3), ///< Control d0-d15, fpscr, fpexc.
+
+       THREADCONTEXT_CONTROL_ALL       = BIT(0) | BIT(1) | BIT(2) | BIT(3), ///< Control all of the above.
+} ThreadContextControlFlags;
+
+/// Thread parameter field for @ref svcGetDebugThreadParameter
+typedef enum {
+       DBGTHREAD_PARAMETER_PRIORITY            = 0, ///< Thread priority.
+       DBGTHREAD_PARAMETER_SCHEDULING_MASK_LOW = 1, ///< Low scheduling mask.
+       DBGTHREAD_PARAMETER_CPU_IDEAL           = 2, ///< Ideal processor.
+       DBGTHREAD_PARAMETER_CPU_CREATOR         = 3, ///< Processor that created the threod.
+} DebugThreadParameter;
+
 ///@}
 
 ///@name Processes
@@ -451,24 +517,6 @@ Result svcInvalidateProcessDataCache(Handle process, void* addr, u32 size);
  * @param size Size of the memory to flush.
  */
 Result svcFlushProcessDataCache(Handle process, void const* addr, u32 size);
-
-/**
- * @brief Reads from a process's memory.
- * @param buffer Buffer to read data to.
- * @param debug Debug handle of the process.
- * @param addr Address to read from.
- * @param size Size of the memory to read.
- */
-Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size);
-
-/**
- * @brief Writes to a process's memory.
- * @param debug Debug handle of the process.
- * @param buffer Buffer to write data from.
- * @param addr Address to write to.
- * @param size Size of the memory to write.
- */
-Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 size);
 ///@}
 
 
@@ -962,11 +1010,75 @@ Result svcTerminateDebugProcess(Handle debug);
 Result svcGetProcessDebugEvent(DebugEventInfo* info, Handle debug);
 
 /**
- * @brief Continues the current debug event of a debugged process.
+ * @brief Continues the current debug event of a debugged process (not necessarily the same as @ref svcGetProcessDebugEvent).
+ * @param debug Debug handle of the process.
+ * @param flags Flags to continue with, see @ref DebugFlags.
+ */
+Result svcContinueDebugEvent(Handle debug, DebugFlags flags);
+
+/**
+ * @brief Fetches the saved registers of a thread, either inactive or awaiting @ref svcContinueDebugEvent, belonging to a debugged process.
+ * @param[out] context Values of the registers to fetch, see @ref ThreadContext.
+ * @param debug Debug handle of the parent process.
+ * @param threadId ID of the thread to fetch the saved registers of.
+ * @param controlFlags Which registers to fetch, see @ref ThreadContextControlFlags.
+ */
+Result svcGetDebugThreadContext(ThreadContext* context, Handle debug, u32 threadId, ThreadContextControlFlags controlFlags);
+
+/**
+ * @brief Updates the saved registers of a thread, either inactive or awaiting @ref svcContinueDebugEvent, belonging to a debugged process.
+ * @param debug Debug handle of the parent process.
+ * @param threadId ID of the thread to update the saved registers of.
+ * @param context Values of the registers to update, see @ref ThreadContext.
+ * @param controlFlags Which registers to update, see @ref ThreadContextControlFlags.
+ */
+Result svcSetDebugThreadContext(Handle debug, u32 threadId, ThreadContext* context, ThreadContextControlFlags controlFlags);
+
+/**
+ * @brief Queries memory information of a debugged process.
+ * @param[out] info Pointer to output memory info to.
+ * @param[out] out Pointer to output page info to.
+ * @param debug Debug handle of the process to query memory from.
+ * @param addr Virtual memory address to query.
+ */
+Result svcQueryDebugProcessMemory(MemInfo* info, PageInfo* out, Handle debug, u32 addr);
+
+/**
+ * @brief Reads from a debugged process's memory.
+ * @param buffer Buffer to read data to.
+ * @param debug Debug handle of the process.
+ * @param addr Address to read from.
+ * @param size Size of the memory to read.
+ */
+Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size);
+
+/**
+ * @brief Writes to a debugged process's memory.
  * @param debug Debug handle of the process.
- * @param flags Flags to continue with.
+ * @param buffer Buffer to write data from.
+ * @param addr Address to write to.
+ * @param size Size of the memory to write.
  */
-Result svcContinueDebugEvent(Handle debug, u32 flags);
+Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 size);
+
+/**
+ * @brief Sets an hardware breakpoint or watchpoint. This is an interface to the BRP/WRP registers, see http://infocenter.arm.com/help/topic/com.arm.doc.ddi0360f/CEGEBGFC.html .
+ * @param registerId range 0..5 = breakpoints (BRP0-5), 0x100..0x101 = watchpoints (WRP0-1). The previous stop point for the register is disabled.
+ * @param control Value of the control regiser.
+ * @param value Value of the value register: either and address (if bit21 of control is clear) or the debug handle of a process to fetch the context ID of.
+ */
+Result svcSetHardwareBreakPoint(s32 registerId, u32 control, u32 value);
+
+/**
+ * @brief Gets a debugged thread's parameter.
+ * @param[out] unused Unused.
+ * @param[out] out Output value.
+ * @param debug Debug handle of the process.
+ * @param threadId ID of the thread
+ * @param parameter Parameter to fetch, see @ref DebugThreadParameter.
+ */
+Result svcGetDebugThreadParam(s64* unused, u32* out, Handle debug, u32 threadId, DebugThreadParameter parameter);
+
 ///@}
 
 /**
@@ -974,3 +1086,6 @@ Result svcContinueDebugEvent(Handle debug, u32 flags);
  * @param callback Function to execute.
  */
 Result svcBackdoor(s32 (*callback)(void));
+
+/// Stop point, does nothing if the process is not attached (as opposed to 'bkpt' instructions)
+#define SVC_STOP_POINT __asm__ volatile("svc 0xFF");
index c694db592e896d47ad5cb9c9ab9d9d48832b92f5..4134cb8deed30220a2a5de1430bfcaec33d1b9be 100644 (file)
@@ -58,3 +58,22 @@ typedef void (*voidfn)(void);
 /// Flags a function as deprecated.
 #define DEPRECATED
 #endif
+
+/// Structure representing CPU registers
+typedef struct {
+       u32 r[13]; ///< r0-r12.
+       u32 sp;    ///< sp.
+       u32 lr;    ///< lr.
+       u32 pc;    ///< pc. May need to be adjusted.
+       u32 cpsr;  ///< cpsr.
+} CpuRegisters;
+
+/// Structure representing FPU registers
+typedef struct {
+       union{
+               double d[16]; ///< d0-d15.
+               float  f[32]; ///< f0-f31.
+       };
+       u32 fpscr;        ///< fpscr.
+       u32 fpexc;        ///< fpexc.
+} FpuRegisters;
index 5447e5e8e899e4921b7d5db243392084f44b988e..d1a3e1015bf241998b9ab76b0928294fa16f493a 100644 (file)
@@ -430,6 +430,25 @@ SVC_BEGIN svcGetProcessList
        add sp, sp, #8
        bx  lr
 
+SVC_BEGIN svcGetDebugThreadContext
+       svc 0x67
+       bx lr
+
+SVC_BEGIN svcSetDebugThreadContext
+       svc 0x68
+       bx lr
+
+SVC_BEGIN svcQueryDebugProcessMemory
+       push {r0, r1, r4-r6}
+       svc 0x69
+       ldr r6, [sp]
+       stm r6, {r1-r4}
+       ldr r6, [sp, #4]
+       str r5, [r6]
+       add sp, sp, #8
+       pop {r4-r6}
+       bx  lr
+
 SVC_BEGIN svcReadProcessMemory
        svc 0x6A
        bx  lr
@@ -438,6 +457,20 @@ SVC_BEGIN svcWriteProcessMemory
        svc 0x6B
        bx  lr
 
+SVC_BEGIN svcSetHardwareBreakPoint
+       svc 0x6C
+       bx  lr
+
+SVC_BEGIN svcGetDebugThreadParam
+       push {r0, r1, r4, r5}
+       ldr r0, [sp, #16]
+       svc 0x6D
+       pop {r4, r5}
+       stm r4, {r1, r2}
+       str r3, [r5]
+       pop {r4, r5}
+       bx lr
+
 SVC_BEGIN svcControlProcessMemory
        push {r4-r5}
        ldr r4, [sp, #0x8]