mirror of
https://github.com/apache/nuttx.git
synced 2026-05-30 05:16:47 +08:00
gdbstub:support gdbstub memory access control
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <elf.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -35,6 +36,7 @@
|
|||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/ascii.h>
|
#include <nuttx/ascii.h>
|
||||||
#include <nuttx/gdbstub.h>
|
#include <nuttx/gdbstub.h>
|
||||||
|
#include <nuttx/memoryregion.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@@ -68,6 +70,7 @@ struct gdb_state_s
|
|||||||
size_t pkt_len; /* Packet send and receive length */
|
size_t pkt_len; /* Packet send and receive length */
|
||||||
uint8_t running_regs[XCPTCONTEXT_SIZE]; /* Registers of running thread */
|
uint8_t running_regs[XCPTCONTEXT_SIZE]; /* Registers of running thread */
|
||||||
size_t size; /* Size of registers */
|
size_t size; /* Size of registers */
|
||||||
|
FAR struct memory_region_s *range; /* Memory regions */
|
||||||
uintptr_t registers[0]; /* Registers of other threads */
|
uintptr_t registers[0]; /* Registers of other threads */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -633,6 +636,7 @@ static ssize_t gdb_hex2bin(FAR void *buf, size_t buf_len,
|
|||||||
in[pos], in[pos + 1], 0
|
in[pos], in[pos + 1], 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
set_errno(0);
|
||||||
out[pos / 2] = strtoul(ch, NULL, 16); /* Decode high nibble */
|
out[pos / 2] = strtoul(ch, NULL, 16); /* Decode high nibble */
|
||||||
if (out[pos / 2] == 0 && get_errno())
|
if (out[pos / 2] == 0 && get_errno())
|
||||||
{
|
{
|
||||||
@@ -703,6 +707,40 @@ static ssize_t gdb_bin2bin(FAR void *buf, size_t buf_len,
|
|||||||
return out_pos;
|
return out_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gdb_is_valid_region
|
||||||
|
* Description:
|
||||||
|
* Check if the address is in the memory region.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static bool gdb_is_valid_region(FAR struct gdb_state_s *state,
|
||||||
|
uintptr_t addr, size_t len, uint32_t flags)
|
||||||
|
{
|
||||||
|
FAR struct memory_region_s *region = state->range;
|
||||||
|
|
||||||
|
if (state->range == NULL)
|
||||||
|
{
|
||||||
|
/* No memory region, so allow all access */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (region->start < region->end)
|
||||||
|
{
|
||||||
|
if (addr >= region->start &&
|
||||||
|
addr <= region->end - len &&
|
||||||
|
(region->flags & flags) == flags)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
region++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Command Functions
|
* Command Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -732,7 +770,14 @@ static ssize_t gdb_get_memory(FAR struct gdb_state_s *state,
|
|||||||
uintptr_t addr, size_t len,
|
uintptr_t addr, size_t len,
|
||||||
gdb_format_func_t format)
|
gdb_format_func_t format)
|
||||||
{
|
{
|
||||||
return format(buf, buf_len, (FAR const void *)addr, len);
|
ssize_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (gdb_is_valid_region(state, addr, len, PF_R))
|
||||||
|
{
|
||||||
|
return format(buf, buf_len, (FAR const void *)addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -760,7 +805,14 @@ static ssize_t gdb_put_memory(FAR struct gdb_state_s *state,
|
|||||||
uintptr_t addr, size_t len,
|
uintptr_t addr, size_t len,
|
||||||
gdb_format_func_t format)
|
gdb_format_func_t format)
|
||||||
{
|
{
|
||||||
return format((FAR void *)addr, len, buf, buf_len);
|
ssize_t ret = -EINVAL;
|
||||||
|
|
||||||
|
if (gdb_is_valid_region(state, addr, len, PF_W))
|
||||||
|
{
|
||||||
|
return format((FAR void *)addr, len, buf, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -1786,6 +1838,16 @@ FAR struct gdb_state_s *gdb_state_init(gdb_send_func_t send,
|
|||||||
state->priv = priv;
|
state->priv = priv;
|
||||||
state->monitor = monitor;
|
state->monitor = monitor;
|
||||||
|
|
||||||
|
if (CONFIG_BOARD_MEMORY_RANGE[0] != '\0')
|
||||||
|
{
|
||||||
|
state->range = alloc_memory_region(CONFIG_BOARD_MEMORY_RANGE);
|
||||||
|
if (state->range == NULL)
|
||||||
|
{
|
||||||
|
lib_free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1804,6 +1866,11 @@ void gdb_state_uninit(FAR struct gdb_state_s *state)
|
|||||||
{
|
{
|
||||||
if (state != NULL)
|
if (state != NULL)
|
||||||
{
|
{
|
||||||
|
if (state->range != NULL)
|
||||||
|
{
|
||||||
|
free_memory_region(state->range);
|
||||||
|
}
|
||||||
|
|
||||||
lib_free(state);
|
lib_free(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ int coredump_add_memory_region(FAR const void *ptr, size_t size)
|
|||||||
{
|
{
|
||||||
region = (FAR struct memory_region_s *)g_regions;
|
region = (FAR struct memory_region_s *)g_regions;
|
||||||
|
|
||||||
while (region->start != 0)
|
while (region->start < region->end)
|
||||||
{
|
{
|
||||||
if ((uintptr_t)ptr >= region->start &&
|
if ((uintptr_t)ptr >= region->start &&
|
||||||
(uintptr_t)ptr + size < region->end)
|
(uintptr_t)ptr + size < region->end)
|
||||||
|
|||||||
Reference in New Issue
Block a user