eclair: fix register GDB response for descheduled threads
Change-Id: I0001d094b624bc03f2b178ec28a4cab51e2acaf0
This commit is contained in:
@ -2,16 +2,19 @@
|
||||
#include <stdio.h>
|
||||
#include <eclair.h>
|
||||
#include <arch-eclair.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <ihk/ihk_host_user.h>
|
||||
|
||||
int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
{
|
||||
int i, ret, total = 0;
|
||||
uint32_t pstate;
|
||||
const unsigned long *regs[] = {&kregs->x19, &kregs->x20, &kregs->x21,
|
||||
&kregs->x22, &kregs->x23, &kregs->x24,
|
||||
&kregs->x25, &kregs->x26, &kregs->x27,
|
||||
&kregs->x28};
|
||||
|
||||
for (i = 0; i < 18; i++) /* x0-x18 */{
|
||||
for (i = 0; i <= 18; i++) /* x0-x18 */{
|
||||
ret = snprintf(rbp, rbp_size, "xxxxxxxxxxxxxxxx");
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -31,7 +34,18 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
rbp_size -= ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) { /* x29-x30 */
|
||||
// X29 FP
|
||||
ret = print_bin(rbp, rbp_size, (void *)&kregs->fp, sizeof(kregs->fp));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
total += ret;
|
||||
dprintf("%s: FP: %s, kregs->fp: 0x%lx\n", __func__, rbp, kregs->fp);
|
||||
rbp += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
// x30 LR
|
||||
for (i = 0; i < 1; i++) {
|
||||
ret = snprintf(rbp, rbp_size, "xxxxxxxxxxxxxxxx");
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -41,12 +55,38 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
rbp_size -= ret;
|
||||
}
|
||||
|
||||
ret += print_bin(rbp, rbp_size, (void *)&kregs->sp, sizeof(kregs->sp));
|
||||
// X31 SP
|
||||
ret = print_bin(rbp, rbp_size, (void *)&kregs->sp, sizeof(kregs->sp));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
total += ret;
|
||||
dprintf("%s: SP: %s, kregs->sp: 0x%lx\n", __func__, rbp, kregs->sp);
|
||||
rbp += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
// X32 PC
|
||||
ret = print_bin(rbp, rbp_size, (void *)&kregs->pc, sizeof(kregs->pc));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
total += ret;
|
||||
dprintf("%s: PC: %s, kregs->pc: 0x%lx\n", __func__, rbp, kregs->pc);
|
||||
rbp += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
// PSTATE
|
||||
#define PSR_MODE_EL1h 0x00000005
|
||||
pstate = PSR_MODE_EL1h;
|
||||
ret = print_bin(rbp, rbp_size, (void *)&pstate, sizeof(pstate));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
total += ret;
|
||||
rbp += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
dprintf("%s: total: %d\n", __func__, total);
|
||||
return total;
|
||||
}
|
||||
|
||||
@ -70,3 +110,24 @@ int arch_setup_constants(void)
|
||||
/* Nothing here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: in ARM64, ctx is a pointer to thread_info, in which
|
||||
* cpu_context is the real member we are looking for thus an extra
|
||||
* indirection is needed.
|
||||
*/
|
||||
int arch_read_kregs(unsigned long ctx, struct arch_kregs *kregs)
|
||||
{
|
||||
int error;
|
||||
error = read_mem(ctx, &ctx, sizeof(ctx));
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: the 16 below is offsetof(struct thread_info, cpu_context)
|
||||
* add this to debug_constants or move the whole thing over DWARF
|
||||
* based inspection...
|
||||
*/
|
||||
return read_mem(ctx + 16, kregs, sizeof(*kregs));
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
total += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
ret += print_bin(rbp, rbp_size, (void *)&kregs->rbx, sizeof(uint64_t)); /* rbx */
|
||||
ret = print_bin(rbp, rbp_size, (void *)&kregs->rbx, sizeof(uint64_t)); /* rbx */
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -44,7 +44,7 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(regs_1)/sizeof(regs_1[0]); i++) { /* rsi, rdi, rbp, rsp */
|
||||
ret = print_bin(rbp, rbp_size, regs_1 + i, sizeof(regs_1[0]));
|
||||
ret = print_bin(rbp, rbp_size, (void *)regs_1[i], sizeof(regs_1[0]));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -64,7 +64,7 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(regs_2)/sizeof(regs_2[0]); i++) { /* r12-r15 */
|
||||
ret = print_bin(rbp, rbp_size, regs_2 + i, sizeof(regs_2[0]));
|
||||
ret = print_bin(rbp, rbp_size, (void *)regs_2[i], sizeof(regs_2[0]));
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -73,7 +73,7 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
rbp_size -= ret;
|
||||
}
|
||||
|
||||
ret += print_bin(rbp, rbp_size, (void *)&ihk_mc_switch_context, sizeof(uint64_t)); /* rip */
|
||||
ret = print_bin(rbp, rbp_size, (void *)&ihk_mc_switch_context, sizeof(uint64_t)); /* rip */
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -81,7 +81,7 @@ int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs)
|
||||
total += ret;
|
||||
rbp_size -= ret;
|
||||
|
||||
ret += print_bin(rbp, rbp_size, (void *)&kregs->rflags, sizeof(uint32_t)); /* rflags */
|
||||
ret = print_bin(rbp, rbp_size, (void *)&kregs->rflags, sizeof(uint32_t)); /* rflags */
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -131,6 +131,11 @@ int arch_setup_constants(void)
|
||||
}
|
||||
|
||||
printf("x86 linux_page_offset: 0x%lx\n", linux_page_offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int arch_read_kregs(unsigned long ctx, struct arch_kregs *kregs)
|
||||
{
|
||||
return read_mem(ctx, kregs, sizeof(*kregs));
|
||||
}
|
||||
|
||||
@ -731,14 +731,14 @@ static void command(const char *cmd, char *res, size_t res_size) {
|
||||
int error;
|
||||
struct arch_kregs kregs;
|
||||
|
||||
error = read_mem(curr_thread->process+K(CTX_OFFSET),
|
||||
&kregs, sizeof(kregs));
|
||||
error = arch_read_kregs(curr_thread->process+K(CTX_OFFSET),
|
||||
&kregs);
|
||||
if (error) {
|
||||
perror("read_mem");
|
||||
perror("arch_read_kregs");
|
||||
break;
|
||||
}
|
||||
|
||||
print_kregs(rbp, res_size, &kregs);
|
||||
rbp += print_kregs(rbp, res_size, &kregs);
|
||||
}
|
||||
else {
|
||||
int error;
|
||||
|
||||
@ -9,16 +9,26 @@
|
||||
#include <arch-eclair.h>
|
||||
|
||||
/* common */
|
||||
int read_mem(uintptr_t va, void *buf, size_t size);
|
||||
#define NOSYMBOL ((uintptr_t)-1)
|
||||
uintptr_t lookup_symbol(char *name);
|
||||
int read_symbol_64(char *name, void *buf);
|
||||
ssize_t print_bin(char *buf, size_t buf_size, void *data, size_t size);
|
||||
|
||||
/* arch depend */
|
||||
int print_kregs(char *rbp, size_t rbp_size, const struct arch_kregs *kregs);
|
||||
int arch_read_kregs(unsigned long ctx, struct arch_kregs *kregs);
|
||||
|
||||
#define NOPHYS ((uintptr_t)-1)
|
||||
uintptr_t virt_to_phys(uintptr_t va);
|
||||
|
||||
int arch_setup_constants(void);
|
||||
|
||||
//#define DEBUG
|
||||
#ifdef DEBUG
|
||||
#define dprintf printf
|
||||
#else
|
||||
#define dprintf(...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_USER_COMMON_ECLAIR_H */
|
||||
|
||||
Reference in New Issue
Block a user