mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 17:58:19 +08:00
libdebugger/target: Add support for backend code writters
The call lets backends support special methods of writing code. Updates #5098
This commit is contained in:
@@ -217,22 +217,31 @@ rtems_debugger_target_swbreak_control(bool insert, uintptr_t addr, DB_UINT kind)
|
||||
if (loc == swbreaks[i].address) {
|
||||
size_t remaining;
|
||||
if (!insert) {
|
||||
if (target->breakpoint_size > 4)
|
||||
memcpy(loc, swbreaks[i].contents, target->breakpoint_size);
|
||||
else {
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = swbreaks[i].contents[3];
|
||||
case 3:
|
||||
loc[2] = swbreaks[i].contents[2];
|
||||
case 2:
|
||||
loc[1] = swbreaks[i].contents[1];
|
||||
case 1:
|
||||
loc[0] = swbreaks[i].contents[0];
|
||||
break;
|
||||
if (target->code_writer != NULL) {
|
||||
r = target->code_writer(loc,
|
||||
&swbreaks[i].contents[0],
|
||||
target->breakpoint_size);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (target->breakpoint_size > 4) {
|
||||
memcpy(loc, &swbreaks[i].contents[0], target->breakpoint_size);
|
||||
} else {
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = swbreaks[i].contents[3];
|
||||
case 3:
|
||||
loc[2] = swbreaks[i].contents[2];
|
||||
case 2:
|
||||
loc[1] = swbreaks[i].contents[1];
|
||||
case 1:
|
||||
loc[0] = swbreaks[i].contents[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
}
|
||||
rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
--target->swbreaks.level;
|
||||
remaining = (target->swbreaks.level - i) * swbreak_size;
|
||||
memmove(&swbreaks[i], &swbreaks[i + 1], remaining);
|
||||
@@ -287,27 +296,36 @@ rtems_debugger_target_swbreak_insert(void)
|
||||
uint8_t* loc = swbreaks[i].address;
|
||||
if (rtems_debugger_verbose())
|
||||
rtems_debugger_printf("rtems-db: bp: in: %p\n", swbreaks[i].address);
|
||||
if (target->breakpoint_size > 4)
|
||||
memcpy(loc, &target->breakpoint[0], target->breakpoint_size);
|
||||
else {
|
||||
if (rtems_debugger_verbose())
|
||||
rtems_debugger_printf("rtems-db: bp: in: %p %p %d %d %d\n",
|
||||
loc, &target->breakpoint[0],
|
||||
(int) target->breakpoint_size,
|
||||
(int) i, (int) target->swbreaks.level);
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = target->breakpoint[3];
|
||||
case 3:
|
||||
loc[2] = target->breakpoint[2];
|
||||
case 2:
|
||||
loc[1] = target->breakpoint[1];
|
||||
case 1:
|
||||
loc[0] = target->breakpoint[0];
|
||||
break;
|
||||
if (target->code_writer != NULL) {
|
||||
r = target->code_writer(loc,
|
||||
&target->breakpoint[0],
|
||||
target->breakpoint_size);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (target->breakpoint_size > 4) {
|
||||
memcpy(loc, &target->breakpoint[0], target->breakpoint_size);
|
||||
} else {
|
||||
if (rtems_debugger_verbose())
|
||||
rtems_debugger_printf("rtems-db: bp: in: %p %p %d %d %d\n",
|
||||
loc, &target->breakpoint[0],
|
||||
(int) target->breakpoint_size,
|
||||
(int) i, (int) target->swbreaks.level);
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = target->breakpoint[3];
|
||||
case 3:
|
||||
loc[2] = target->breakpoint[2];
|
||||
case 2:
|
||||
loc[1] = target->breakpoint[1];
|
||||
case 1:
|
||||
loc[0] = target->breakpoint[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
}
|
||||
r = rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
@@ -328,22 +346,29 @@ rtems_debugger_target_swbreak_remove(void)
|
||||
uint8_t* contents = &swbreaks[i].contents[0];
|
||||
if (rtems_debugger_verbose())
|
||||
rtems_debugger_printf("rtems-db: bp: out: %p\n", swbreaks[i].address);
|
||||
if (target->breakpoint_size > 4)
|
||||
memcpy(loc, contents, target->breakpoint_size);
|
||||
else {
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = contents[3];
|
||||
case 3:
|
||||
loc[2] = contents[2];
|
||||
case 2:
|
||||
loc[1] = contents[1];
|
||||
case 1:
|
||||
loc[0] = contents[0];
|
||||
break;
|
||||
if (target->code_writer != NULL) {
|
||||
r = target->code_writer(loc, contents, target->breakpoint_size);
|
||||
if (r < 0) {
|
||||
return r;
|
||||
}
|
||||
} else {
|
||||
if (target->breakpoint_size > 4) {
|
||||
memcpy(loc, contents, target->breakpoint_size);
|
||||
} else {
|
||||
switch (target->breakpoint_size) {
|
||||
case 4:
|
||||
loc[3] = contents[3];
|
||||
case 3:
|
||||
loc[2] = contents[2];
|
||||
case 2:
|
||||
loc[1] = contents[1];
|
||||
case 1:
|
||||
loc[0] = contents[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
r = rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
}
|
||||
r = rtems_debugger_target_cache_sync(&swbreaks[i]);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
|
||||
@@ -91,6 +91,15 @@ typedef struct rtems_debugger_target_swbreak {
|
||||
uint8_t contents[RTEMS_DEBUGGER_TARGET_SWBREAK_MAX_SIZE];
|
||||
} rtems_debugger_target_swbreak;
|
||||
|
||||
/**
|
||||
* Target memory update handler. If set this is called to modify
|
||||
* the executable memory. It may not be possible to make it
|
||||
* read/write.
|
||||
*/
|
||||
typedef int (*rtems_debugger_target_code_writer)(void* address,
|
||||
const void* data,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* The target data.
|
||||
*
|
||||
@@ -99,16 +108,17 @@ typedef struct rtems_debugger_target_swbreak {
|
||||
* the last entry is the size of the register table.
|
||||
*/
|
||||
typedef struct rtems_debugger_target {
|
||||
int capabilities; /*<< The capabilities to report. */
|
||||
size_t reg_num; /*<< The number of registers. */
|
||||
const size_t* reg_offset; /*<< The reg offsettable, len = reg_num + 1. */
|
||||
const uint8_t* breakpoint; /*<< The breakpoint instruction(s). */
|
||||
size_t breakpoint_size; /*<< The breakpoint size. */
|
||||
rtems_debugger_block swbreaks; /*<< The software breakpoint block. */
|
||||
bool memory_access; /*<< Accessing target memory. */
|
||||
jmp_buf access_return; /*<< Return from an access fault. */
|
||||
uintptr_t step_bp_address; /*<< Stepping break point address */
|
||||
rtems_id step_tid; /*<< Stepping task id */
|
||||
int capabilities; /*<< The capabilities to report. */
|
||||
size_t reg_num; /*<< The number of registers. */
|
||||
const size_t* reg_offset; /*<< The reg offsettable, len = reg_num + 1. */
|
||||
const uint8_t* breakpoint; /*<< The breakpoint instruction(s). */
|
||||
size_t breakpoint_size; /*<< The breakpoint size. */
|
||||
rtems_debugger_block swbreaks; /*<< The software breakpoint block. */
|
||||
rtems_debugger_target_code_writer code_writer; /*<< If set use to write to code memory */
|
||||
bool memory_access; /*<< Accessing target memory. */
|
||||
jmp_buf access_return; /*<< Return from an access fault. */
|
||||
uintptr_t step_bp_address; /*<< Stepping break point address */
|
||||
rtems_id step_tid; /*<< Stepping task id */
|
||||
|
||||
} rtems_debugger_target;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user