librz/bin: fix regstate load in ELF corefiles for x86_64 (#6195)
* regstate retrieval in ELF corefiles * remove rzbin call from cmd_debug * increase FP_LAYOUT to 128
This commit is contained in:
parent
245e198cf1
commit
9007cde56e
4 changed files with 83 additions and 4 deletions
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#define ROUND_UP_4(x) ((x) + (4 - 1)) / 4 * 4
|
||||
|
||||
#define FP_LAYOUT 0x10
|
||||
#define FP_LAYOUT 0x80
|
||||
|
||||
#define X86 0
|
||||
#define X86_64 1
|
||||
|
|
@ -154,6 +154,13 @@
|
|||
#define SPARC64_OPENBSD_FPREGS_SIZE ((4 * 64) + 8 + 4)
|
||||
#define SPARC64_OPENBSD_FPREG_OFFSET 0x0
|
||||
|
||||
// Linux x86/x86_64 NT_FPREGSET layouts.
|
||||
// For both, the FP state begins at the start of the note description.
|
||||
#define X86_FPREGS_SIZE 108
|
||||
#define X86_64_FPREGS_SIZE 512
|
||||
#define X86_FPREG_OFFSET 0x0
|
||||
#define X86_64_FPREG_OFFSET 0x0
|
||||
|
||||
// o6 is the stack pointer. So g0-g7,o0-5 come before it.
|
||||
// Same for OpenBSD and Linux.
|
||||
#define SPARC32_PR_STATUS_REG_OFFSET_SP (4 * 14)
|
||||
|
|
@ -214,6 +221,10 @@ static RzBinElfPrStatusLayout prstatus_layouts[ARCH_LEN] = {
|
|||
|
||||
[RISCV_32] = { RISCV_32_REGS_SIZE, RISCV_32_REG_OFFSET, 32, RISCV_32_REG_OFFSET_SP },
|
||||
[RISCV_64] = { RISCV_64_REGS_SIZE, RISCV_64_REG_OFFSET, 64, RISCV_64_REG_OFFSET_SP },
|
||||
|
||||
[X86 | FP_LAYOUT] = { X86_FPREGS_SIZE, X86_FPREG_OFFSET, 0, 0 },
|
||||
[X86_64 |
|
||||
FP_LAYOUT] = { X86_64_FPREGS_SIZE, X86_64_FPREG_OFFSET, 0, 0 },
|
||||
};
|
||||
|
||||
static bool parse_register_note(ELFOBJ *bin, RzVector /*<RzBinElfNote>*/ *notes, Elf_(Nhdr) * note_segment_header, ut64 offset, size_t n_type) {
|
||||
|
|
@ -500,6 +511,22 @@ RZ_BORROW RzBinElfPrStatusLayout *Elf_(rz_bin_elf_get_regset_layout)(RZ_NONNULL
|
|||
switch (bin->ehdr.e_machine) {
|
||||
default:
|
||||
return NULL;
|
||||
case EM_386:
|
||||
if (n_type == NT_FPREGSET) {
|
||||
off = FP_LAYOUT | X86;
|
||||
} else {
|
||||
rz_warn_if_reached();
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case EM_X86_64:
|
||||
if (n_type == NT_FPREGSET) {
|
||||
off = FP_LAYOUT | X86_64;
|
||||
} else {
|
||||
rz_warn_if_reached();
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case EM_MIPS:
|
||||
/* fall-thru */
|
||||
case EM_MIPS_RS3_LE:
|
||||
|
|
|
|||
|
|
@ -1163,6 +1163,12 @@ RZ_API bool rz_core_bin_load(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filen
|
|||
} else {
|
||||
RZ_LOG_INFO("Setting up coredump: Registers have been set\n");
|
||||
}
|
||||
if (!RZ_STR_ISEMPTY(rreg->reg_profile_str)) {
|
||||
rz_reg_set_profile_string(r->dbg->reg, rreg->reg_profile_str);
|
||||
if (binfile->o->regstate && rz_reg_arena_set_bytes(r->dbg->reg, binfile->o->regstate)) {
|
||||
RZ_LOG_WARN("Setting up coredump: Problem while setting debug registers\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -6,15 +6,42 @@
|
|||
#include <rz_cons.h>
|
||||
#include <rz_reg.h>
|
||||
|
||||
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write) {
|
||||
int i, n, size;
|
||||
if (!dbg || !dbg->reg || !dbg->cur) {
|
||||
static bool rz_debug_reg_sync_from_regstate(RzDebug *dbg) {
|
||||
if (!dbg || !dbg->corebind.core) {
|
||||
return false;
|
||||
}
|
||||
RzCore *core = (RzCore *)dbg->corebind.core;
|
||||
RzBinFile *bf = rz_bin_cur(core->bin);
|
||||
if (!bf || !bf->o || !bf->o->regstate) {
|
||||
return false;
|
||||
}
|
||||
RzReg *areg = core->analysis ? rz_analysis_get_reg(core->analysis) : NULL;
|
||||
const char *profile = areg ? areg->reg_profile_str : NULL;
|
||||
if (!RZ_STR_ISEMPTY(profile)) {
|
||||
rz_reg_set_profile_string(dbg->reg, profile);
|
||||
}
|
||||
return rz_reg_arena_set_bytes(dbg->reg, bf->o->regstate) == 0;
|
||||
}
|
||||
|
||||
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write) {
|
||||
int i, n, size;
|
||||
if (!dbg || !dbg->reg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!write && (!dbg->cur || (!dbg->cur->reg_read && !dbg->cur->sync_registers) || rz_debug_is_dead(dbg))) {
|
||||
if (rz_debug_reg_sync_from_regstate(dbg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// There's no point in syncing a dead target
|
||||
if (rz_debug_is_dead(dbg)) {
|
||||
return false;
|
||||
}
|
||||
if (!dbg->cur) {
|
||||
return false;
|
||||
}
|
||||
// Check if the functions needed are available
|
||||
if (write && !dbg->cur->reg_write && !dbg->cur->sync_registers) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ NAME=core regs linux x86_64
|
|||
FILE=bins/elf/core/core-linux-x86_64
|
||||
CMDS=<<EOF
|
||||
ar
|
||||
dr
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rax = 0x0000000000000000
|
||||
|
|
@ -165,6 +166,24 @@ rip = 0x000056149dfb014d
|
|||
rbp = 0x00007ffc8354c0c0
|
||||
rflags = 0x0000000000010202
|
||||
rsp = 0x00007ffc8354c0b0
|
||||
rax = 0x0000000000000000
|
||||
rbx = 0x000056149dfb0170
|
||||
rcx = 0x00007f582fbf1598
|
||||
rdx = 0x00007ffc8354c1c8
|
||||
rsi = 0x00007ffc8354c1b8
|
||||
rdi = 0x0000000000000001
|
||||
r8 = 0x0000000000000000
|
||||
r9 = 0x00007f582fc5c070
|
||||
r10 = 0x00000000069682ac
|
||||
r11 = 0x0000000000000202
|
||||
r12 = 0x000056149dfb0040
|
||||
r13 = 0x0000000000000000
|
||||
r14 = 0x0000000000000000
|
||||
r15 = 0x0000000000000000
|
||||
rip = 0x000056149dfb014d
|
||||
rbp = 0x00007ffc8354c0c0
|
||||
rflags = 0x0000000000010202
|
||||
rsp = 0x00007ffc8354c0b0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue