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:
Mohammed Muqeet Us Salam 2026-05-01 09:37:59 +05:30 committed by GitHub
parent 245e198cf1
commit 9007cde56e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 83 additions and 4 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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;

View file

@ -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