mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 11:03:11 +00:00
fix(esp_hw_support): validate esp_cpu debug helper args
Reject invalid breakpoint/watchpoint indices and validate watchpoint size before alignment checks. This makes the APIs match their documented contract and avoids crashing on invalid input. Made-with: Cursor
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -72,10 +72,10 @@ void esp_cpu_wait_for_intr(void)
|
||||
#if SOC_CPU_BREAKPOINTS_NUM > 0
|
||||
esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr)
|
||||
{
|
||||
/*
|
||||
Todo:
|
||||
- Check that bp_num is in range
|
||||
*/
|
||||
if (bp_num < 0 || bp_num >= SOC_CPU_BREAKPOINTS_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if __XTENSA__
|
||||
xt_utils_set_breakpoint(bp_num, (uint32_t)bp_addr);
|
||||
#else
|
||||
@@ -101,10 +101,10 @@ esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr)
|
||||
|
||||
esp_err_t esp_cpu_clear_breakpoint(int bp_num)
|
||||
{
|
||||
/*
|
||||
Todo:
|
||||
- Check if the bp_num is valid
|
||||
*/
|
||||
if (bp_num < 0 || bp_num >= SOC_CPU_BREAKPOINTS_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if __XTENSA__
|
||||
xt_utils_clear_breakpoint(bp_num);
|
||||
#else
|
||||
@@ -126,23 +126,20 @@ esp_err_t esp_cpu_clear_breakpoint(int bp_num)
|
||||
#if SOC_CPU_WATCHPOINTS_NUM > 0
|
||||
esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, esp_cpu_watchpoint_trigger_t trigger)
|
||||
{
|
||||
/*
|
||||
Todo:
|
||||
- Check if the wp_num is already in use
|
||||
*/
|
||||
if (wp_num < 0 || wp_num >= SOC_CPU_WATCHPOINTS_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Check if size is 2^n, and size is in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE]
|
||||
if (size < 1 || size > SOC_CPU_WATCHPOINT_MAX_REGION_SIZE || (size & (size - 1)) != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Check that the watched region's start address is naturally aligned to the size of the region
|
||||
if ((uint32_t)wp_addr % size) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// Check if size is 2^n, and size is in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE]
|
||||
if (size < 1 || size > SOC_CPU_WATCHPOINT_MAX_REGION_SIZE || (size & (size - 1)) != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
bool on_read = (trigger == ESP_CPU_WATCHPOINT_LOAD || trigger == ESP_CPU_WATCHPOINT_ACCESS);
|
||||
bool on_write = (trigger == ESP_CPU_WATCHPOINT_STORE || trigger == ESP_CPU_WATCHPOINT_ACCESS);
|
||||
#if __XTENSA__
|
||||
@@ -166,10 +163,10 @@ esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, e
|
||||
|
||||
esp_err_t esp_cpu_clear_watchpoint(int wp_num)
|
||||
{
|
||||
/*
|
||||
Todo:
|
||||
- Check if the wp_num is valid
|
||||
*/
|
||||
if (wp_num < 0 || wp_num >= SOC_CPU_WATCHPOINTS_NUM) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#if __XTENSA__
|
||||
xt_utils_clear_watchpoint(wp_num);
|
||||
#else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -110,6 +110,10 @@ void esp_cpu_reset(int core_id);
|
||||
* This function causes the current CPU core to execute its Wait For Interrupt
|
||||
* (WFI or equivalent) instruction. After executing this function, the CPU core
|
||||
* will stop execution until an interrupt occurs.
|
||||
*
|
||||
* @note On some RISC-V targets, if a debugger is attached while the hardware
|
||||
* wait mode is disabled, this function may return immediately instead of
|
||||
* entering WFI. This keeps debugger memory access working.
|
||||
*/
|
||||
void esp_cpu_wait_for_intr(void);
|
||||
|
||||
@@ -441,12 +445,12 @@ FORCE_INLINE_ATTR void esp_cpu_intr_set_handler(int intr_num, esp_cpu_intr_handl
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a handler function's argument of
|
||||
* @brief Get a handler function's argument
|
||||
*
|
||||
* Get the argument of a previously assigned handler function on the current CPU.
|
||||
*
|
||||
* @param intr_num Interrupt number (from 0 to 31)
|
||||
* @return The the argument passed to the handler function
|
||||
* @return The argument passed to the handler function
|
||||
*/
|
||||
FORCE_INLINE_ATTR void *esp_cpu_intr_get_handler_arg(int intr_num)
|
||||
{
|
||||
@@ -554,7 +558,10 @@ void esp_cpu_configure_region_protection(void);
|
||||
* @note Overwrites previously set breakpoint with same breakpoint number.
|
||||
* @param bp_num Hardware breakpoint number [0..SOC_CPU_BREAKPOINTS_NUM - 1]
|
||||
* @param bp_addr Address to set a breakpoint on
|
||||
* @return ESP_OK if breakpoint is set. Failure otherwise
|
||||
* @return
|
||||
* - ESP_OK if the breakpoint is set
|
||||
* - ESP_ERR_INVALID_ARG if `bp_num` is out of range
|
||||
* - ESP_ERR_INVALID_RESPONSE if setting the breakpoint via semihosting fails
|
||||
*/
|
||||
esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr);
|
||||
|
||||
@@ -563,7 +570,10 @@ esp_err_t esp_cpu_set_breakpoint(int bp_num, const void *bp_addr);
|
||||
*
|
||||
* @note Clears a breakpoint regardless of whether it was previously set
|
||||
* @param bp_num Hardware breakpoint number [0..SOC_CPU_BREAKPOINTS_NUM - 1]
|
||||
* @return ESP_OK if breakpoint is cleared. Failure otherwise
|
||||
* @return
|
||||
* - ESP_OK if the breakpoint is cleared
|
||||
* - ESP_ERR_INVALID_ARG if `bp_num` is out of range
|
||||
* - ESP_ERR_INVALID_RESPONSE if clearing the breakpoint via semihosting fails
|
||||
*/
|
||||
esp_err_t esp_cpu_clear_breakpoint(int bp_num);
|
||||
|
||||
@@ -587,7 +597,10 @@ esp_err_t esp_cpu_clear_breakpoint(int bp_num);
|
||||
* @param wp_addr Watchpoint's base address, must be naturally aligned to the size of the region
|
||||
* @param size Size of the region to watch. Must be one of 2^n and in the range of [1 ... SOC_CPU_WATCHPOINT_MAX_REGION_SIZE]
|
||||
* @param trigger Trigger type
|
||||
* @return ESP_ERR_INVALID_ARG on invalid arg, ESP_OK otherwise
|
||||
* @return
|
||||
* - ESP_OK if the watchpoint is set
|
||||
* - ESP_ERR_INVALID_ARG if `wp_num`, `wp_addr`, or `size` is invalid
|
||||
* - ESP_ERR_INVALID_RESPONSE if setting the watchpoint via semihosting fails
|
||||
*/
|
||||
esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, esp_cpu_watchpoint_trigger_t trigger);
|
||||
|
||||
@@ -596,7 +609,10 @@ esp_err_t esp_cpu_set_watchpoint(int wp_num, const void *wp_addr, size_t size, e
|
||||
*
|
||||
* @note Clears a watchpoint regardless of whether it was previously set
|
||||
* @param wp_num Hardware watchpoint number [0..SOC_CPU_WATCHPOINTS_NUM - 1]
|
||||
* @return ESP_OK if watchpoint was cleared. Failure otherwise.
|
||||
* @return
|
||||
* - ESP_OK if the watchpoint is cleared
|
||||
* - ESP_ERR_INVALID_ARG if `wp_num` is out of range
|
||||
* - ESP_ERR_INVALID_RESPONSE if clearing the watchpoint via semihosting fails
|
||||
*/
|
||||
esp_err_t esp_cpu_clear_watchpoint(int wp_num);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user