Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /*
0002  * Copyright (c) 2016-2017 Chris Johns <chrisj@rtems.org>.
0003  * All rights reserved.
0004  *
0005  * Redistribution and use in source and binary forms, with or without
0006  * modification, are permitted provided that the following conditions
0007  * are met:
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
0015  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0016  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0017  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
0018  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0019  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0020  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0021  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0022  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0023  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0024  * SUCH DAMAGE.
0025  */
0026 
0027 /*
0028  * Debugger for RTEMS.
0029  */
0030 
0031 #ifndef _RTEMS_DEBUGGER_TARGET_h
0032 #define _RTEMS_DEBUGGER_TARGET_h
0033 
0034 #include <setjmp.h>
0035 
0036 #include <rtems/rtems-debugger.h>
0037 
0038 #include "rtems-debugger-threads.h"
0039 
0040 #ifdef __cplusplus
0041 extern "C" {
0042 #endif /* __cplusplus */
0043 
0044 /*
0045  * Software breakpoint block size.
0046  */
0047 #define RTEMS_DEBUGGER_TARGET_SWBREAK_NUM 64
0048 
0049 /**
0050  * Target capabilities mask.
0051  */
0052 #define RTEMS_DEBUGGER_TARGET_CAP_SWBREAK      (1 << 0)
0053 #define RTEMS_DEBUGGER_TARGET_CAP_HWBREAK      (1 << 1)
0054 #define RTEMS_DEBUGGER_TARGET_CAP_HWWATCH      (1 << 2)
0055 /*
0056  * This target capability indicates that the target implementation uses a pure
0057  * software break implementation which must not allow breakpoints to be
0058  * inserted before the actual switch to the thread, be it in interrupt context
0059  * or otherwise. Such implementations must necessarily implement a thread
0060  * switch hook and interrupt hooks to handle these situations.
0061  */
0062 #define RTEMS_DEBUGGER_TARGET_CAP_PURE_SWBREAK (1 << 3)
0063 
0064 /**
0065  * Types of hardware breakpoints.
0066  */
0067 typedef enum rtems_debugger_target_watchpoint
0068 {
0069   rtems_debugger_target_hw_read,
0070   rtems_debugger_target_hw_write,
0071   rtems_debugger_target_hw_read_write,
0072   rtems_debugger_target_hw_execute
0073 } rtems_debugger_target_watchpoint;
0074 
0075 /**
0076  * Target exception actions.
0077  */
0078 typedef enum rtems_debugger_target_exc_action
0079 {
0080   rtems_debugger_target_exc_consumed, /*<< The exception has been consumed. */
0081   rtems_debugger_target_exc_cascade,  /*<< Cascade to a previous handler. */
0082   rtems_debugger_target_exc_step,     /*<< Step an instruction. */
0083 } rtems_debugger_target_exc_action;
0084 
0085 /**
0086  * Memory breakpoint. We use thumb mode BKPT which is 2 bytes.
0087  */
0088 #define RTEMS_DEBUGGER_TARGET_SWBREAK_MAX_SIZE (4)
0089 typedef struct rtems_debugger_target_swbreak {
0090   void*   address;
0091   uint8_t contents[RTEMS_DEBUGGER_TARGET_SWBREAK_MAX_SIZE];
0092 } rtems_debugger_target_swbreak;
0093 
0094 /**
0095  * Target executable memory update handler. If set the handler is
0096  * called to modify the executable memory. The target's executable
0097  * memory may not be directly writable. The handler is responsible for
0098  * making sure the code update is ready to be executed, for example
0099  * caches are flushed.
0100  */
0101 typedef int (*rtems_debugger_target_code_writer)(void*       address,
0102                                                  const void* data,
0103                                                  size_t      size);
0104 
0105 /**
0106  * The target data.
0107  *
0108  * reg_offset: Table of size_t offset of a register in the register
0109  *             table. The table has one more entry than reg_num where
0110  *             the last entry is the size of the register table.
0111  */
0112 typedef struct rtems_debugger_target {
0113   int                               capabilities;     /*<< The capabilities to report. */
0114   size_t                            reg_num;          /*<< The number of registers. */
0115   const size_t*                     reg_offset;       /*<< The reg offsettable, len = reg_num + 1. */
0116   const uint8_t*                    breakpoint;       /*<< The breakpoint instruction(s). */
0117   size_t                            breakpoint_size;  /*<< The breakpoint size. */
0118   rtems_debugger_block              swbreaks;         /*<< The software breakpoint block. */
0119   rtems_debugger_target_code_writer code_writer;      /*<< If set use to write to code memory */
0120   bool                              memory_access;    /*<< Accessing target memory. */
0121   jmp_buf                           access_return;    /*<< Return from an access fault. */
0122   uintptr_t                         step_bp_address;  /*<< Stepping break point address */
0123   rtems_id                          step_tid;         /*<< Stepping task id */
0124 
0125 } rtems_debugger_target;
0126 
0127 /**
0128  * Create the target.
0129  */
0130 extern int rtems_debugger_target_create(void);
0131 
0132 /**
0133  * Destroy the target.
0134  */
0135 extern int rtems_debugger_target_destroy(void);
0136 
0137 /**
0138  * Configure the target. This is architecture specific.
0139  */
0140 extern int rtems_debugger_target_configure(rtems_debugger_target* target);
0141 
0142 /**
0143  * Enable the target.
0144  */
0145 extern int rtems_debugger_target_enable(void);
0146 
0147 /**
0148  * Disable the target.
0149  */
0150 extern int rtems_debugger_target_disable(void);
0151 
0152 /**
0153  * Return the capabilities mask for the target.
0154  */
0155 extern uint32_t rtems_debugger_target_capabilities(void);
0156 
0157 /**
0158  * Return the number of regisers.
0159  */
0160 extern size_t rtems_debugger_target_reg_num(void);
0161 
0162 /**
0163  * Return the offset of a register in the register table.
0164  */
0165 extern size_t rtems_debugger_target_reg_size(size_t reg);
0166 
0167 /**
0168  * Return the offset of a register in the register table.
0169  */
0170 extern size_t rtems_debugger_target_reg_offset(size_t reg);
0171 
0172 /**
0173  * Return the size of register table.
0174  */
0175 extern size_t rtems_debugger_target_reg_table_size(void);
0176 
0177 /**
0178  * Read the regosters.
0179  */
0180 extern int rtems_debugger_target_read_regs(rtems_debugger_thread* thread);
0181 
0182 /**
0183  * Write the regosters.
0184  */
0185 extern int rtems_debugger_target_write_regs(rtems_debugger_thread* thread);
0186 
0187 /**
0188  * Return the thread's program counter (PC).
0189  */
0190 extern uintptr_t rtems_debugger_target_reg_pc(rtems_debugger_thread* thread);
0191 
0192 /**
0193  * Return the frame's program counter (PC).
0194  */
0195 extern uintptr_t rtems_debugger_target_frame_pc(CPU_Exception_frame* frame);
0196 
0197 /**
0198  * Return the thread's stack pointer (SP).
0199  */
0200 extern uintptr_t rtems_debugger_target_reg_sp(rtems_debugger_thread* thread);
0201 
0202 /**
0203  * Return the thread's TCB stack pointer (SP).
0204  */
0205 extern uintptr_t rtems_debugger_target_tcb_sp(rtems_debugger_thread* thread);
0206 
0207 /**
0208  * The thread is stepping. Setup the thread to step an instruction.
0209  */
0210 extern int rtems_debugger_target_thread_stepping(rtems_debugger_thread* thread);
0211 
0212 /**
0213  * Return the signal for the exception.
0214  */
0215 extern int rtems_debugger_target_exception_to_signal(CPU_Exception_frame* frame);
0216 
0217 /**
0218  * Print the target exception registers.
0219  */
0220 extern void rtems_debugger_target_exception_print(CPU_Exception_frame* frame);
0221 
0222 /**
0223  * Software breakpoints. These are also referred to as memory breakpoints.
0224  */
0225 extern int rtems_debugger_target_swbreak_control(bool    insert,
0226                                                  uintptr_t addr,
0227                                                  DB_UINT kind);
0228 
0229 /**
0230  * Insert software breakpoints into the memory.
0231  */
0232 extern int rtems_debugger_target_swbreak_insert(void);
0233 
0234 /**
0235  * Remove software breakpoints from the memory.
0236  */
0237 extern int rtems_debugger_target_swbreak_remove(void);
0238 
0239 /**
0240  * Determine whether a software breakpoint is configured for the given address.
0241  */
0242 extern bool rtems_debugger_target_swbreak_is_configured( uintptr_t addr );
0243 
0244 /**
0245  * Insert hardware breakpoints into the hardware.
0246  */
0247 extern int rtems_debugger_target_hwbreak_insert(void);
0248 
0249 /**
0250  * Remove hardware breakpoints from the hardware.
0251  */
0252 extern int rtems_debugger_target_hwbreak_remove(void);
0253 
0254 /**
0255  * Hardware breakpoints.
0256  */
0257 extern int rtems_debugger_target_hwbreak_control(rtems_debugger_target_watchpoint type,
0258                                                  bool                             insert,
0259                                                  uintptr_t                        addr,
0260                                                  DB_UINT                          kind);
0261 
0262 /**
0263  * Target exception processor.
0264  */
0265 extern rtems_debugger_target_exc_action
0266 rtems_debugger_target_exception(CPU_Exception_frame* frame);
0267 
0268 /**
0269  * See if the thread is an exception thread.
0270  */
0271 extern void rtems_debugger_target_exception_thread(rtems_debugger_thread* thread);
0272 
0273 /**
0274  * If the thread is an exception thread, resume it.
0275  */
0276 extern void rtems_debugger_target_exception_thread_resume(rtems_debugger_thread* thread);
0277 
0278 /**
0279  * Target instruction cache sync. This depends on the target but it normally
0280  * means a data cache flush and an instruction cache invalidate.
0281  */
0282 extern int rtems_debugger_target_cache_sync(rtems_debugger_target_swbreak* swbreak);
0283 
0284 /**
0285  * Start a target memory access. If 0 is return the access can proceed and if
0286  * -1 is return the access has failed.
0287  */
0288 extern int rtems_debugger_target_start_memory_access(void);
0289 
0290 /**
0291  * End a target memory access.
0292  */
0293 extern void rtems_debugger_target_end_memory_access(void);
0294 
0295 /**
0296  * Is this a target memory access?
0297  */
0298 extern bool rtems_debugger_target_is_memory_access(void);
0299 
0300 #ifdef __cplusplus
0301 }
0302 #endif /* __cplusplus */
0303 
0304 
0305 #endif