librz/bin: add corefile support for Linux MIPS 32/64 (#5355)

This commit is contained in:
Giovanni 2025-09-10 23:12:53 +08:00 committed by GitHub
parent bc30c934fc
commit 46009de0fa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 305 additions and 124 deletions

View file

@ -931,42 +931,80 @@ static char *mips_get_reg_profile(RzAnalysis *analysis) {
"=A3 a3\n"
"=R0 v0\n"
"=R1 v1\n"
"gpr zero .32 ? 0\n"
"gpr at .32 4 0\n"
"gpr v0 .32 8 0\n"
"gpr v1 .32 12 0\n"
"gpr a0 .32 16 0\n"
"gpr a1 .32 20 0\n"
"gpr a2 .32 24 0\n"
"gpr a3 .32 28 0\n"
"gpr t0 .32 32 0\n"
"gpr t1 .32 36 0\n"
"gpr t2 .32 40 0\n"
"gpr t3 .32 44 0\n"
"gpr t4 .32 48 0\n"
"gpr t5 .32 52 0\n"
"gpr t6 .32 56 0\n"
"gpr t7 .32 60 0\n"
"gpr s0 .32 64 0\n"
"gpr s1 .32 68 0\n"
"gpr s2 .32 72 0\n"
"gpr s3 .32 76 0\n"
"gpr s4 .32 80 0\n"
"gpr s5 .32 84 0\n"
"gpr s6 .32 88 0\n"
"gpr s7 .32 92 0\n"
"gpr t8 .32 96 0\n"
"gpr t9 .32 100 0\n"
"gpr k0 .32 104 0\n"
"gpr k1 .32 108 0\n"
"gpr gp .32 112 0\n"
"gpr sp .32 116 0\n"
"gpr fp .32 120 0\n"
"gpr ra .32 124 0\n"
"gpr pc .32 128 0\n"
"gpr hi .32 132 0\n"
"gpr lo .32 136 0\n"
"gpr t .32 140 0\n";
"gpr zero .32 ? 0\n"
"gpr at .32 4 0\n"
"gpr v0 .32 8 0\n"
"gpr v1 .32 12 0\n"
"gpr a0 .32 16 0\n"
"gpr a1 .32 20 0\n"
"gpr a2 .32 24 0\n"
"gpr a3 .32 28 0\n"
"gpr t0 .32 32 0\n"
"gpr t1 .32 36 0\n"
"gpr t2 .32 40 0\n"
"gpr t3 .32 44 0\n"
"gpr t4 .32 48 0\n"
"gpr t5 .32 52 0\n"
"gpr t6 .32 56 0\n"
"gpr t7 .32 60 0\n"
"gpr s0 .32 64 0\n"
"gpr s1 .32 68 0\n"
"gpr s2 .32 72 0\n"
"gpr s3 .32 76 0\n"
"gpr s4 .32 80 0\n"
"gpr s5 .32 84 0\n"
"gpr s6 .32 88 0\n"
"gpr s7 .32 92 0\n"
"gpr t8 .32 96 0\n"
"gpr t9 .32 100 0\n"
"gpr k0 .32 104 0\n"
"gpr k1 .32 108 0\n"
"gpr gp .32 112 0\n"
"gpr sp .32 116 0\n"
"gpr fp .32 120 0\n"
"gpr ra .32 124 0\n"
"gpr lo .32 128 0\n"
"gpr hi .32 132 0\n"
"gpr pc .32 136 0\n"
"gpr badvaddr .32 140 0\n"
"gpr status .32 144 0\n"
"gpr cause .32 148 0\n"
"fpu f0 .32 152 0\n"
"fpu f1 .32 156 0\n"
"fpu f2 .32 160 0\n"
"fpu f3 .32 164 0\n"
"fpu f4 .32 168 0\n"
"fpu f5 .32 172 0\n"
"fpu f6 .32 176 0\n"
"fpu f7 .32 180 0\n"
"fpu f8 .32 184 0\n"
"fpu f9 .32 188 0\n"
"fpu f10 .32 192 0\n"
"fpu f11 .32 196 0\n"
"fpu f12 .32 200 0\n"
"fpu f13 .32 204 0\n"
"fpu f14 .32 208 0\n"
"fpu f15 .32 212 0\n"
"fpu f16 .32 216 0\n"
"fpu f17 .32 220 0\n"
"fpu f18 .32 224 0\n"
"fpu f19 .32 228 0\n"
"fpu f20 .32 232 0\n"
"fpu f21 .32 236 0\n"
"fpu f22 .32 240 0\n"
"fpu f23 .32 244 0\n"
"fpu f24 .32 248 0\n"
"fpu f25 .32 252 0\n"
"fpu f26 .32 256 0\n"
"fpu f27 .32 260 0\n"
"fpu f28 .32 264 0\n"
"fpu f29 .32 268 0\n"
"fpu f30 .32 272 0\n"
"fpu f31 .32 276 0\n"
"fpu fcsr .32 280 0\n"
"fpu fir .32 284 0\n"
"fpu restart .32 288 0\n"
"gpr t .32 292 0\n";
break;
case 64:
p =
@ -980,42 +1018,80 @@ static char *mips_get_reg_profile(RzAnalysis *analysis) {
"=SN v0\n"
"=R0 v0\n"
"=R1 v1\n"
"gpr zero .64 ? 0\n"
"gpr at .64 8 0\n"
"gpr v0 .64 16 0\n"
"gpr v1 .64 24 0\n"
"gpr a0 .64 32 0\n"
"gpr a1 .64 40 0\n"
"gpr a2 .64 48 0\n"
"gpr a3 .64 56 0\n"
"gpr t0 .64 64 0\n"
"gpr t1 .64 72 0\n"
"gpr t2 .64 80 0\n"
"gpr t3 .64 88 0\n"
"gpr t4 .64 96 0\n"
"gpr t5 .64 104 0\n"
"gpr t6 .64 112 0\n"
"gpr t7 .64 120 0\n"
"gpr s0 .64 128 0\n"
"gpr s1 .64 136 0\n"
"gpr s2 .64 144 0\n"
"gpr s3 .64 152 0\n"
"gpr s4 .64 160 0\n"
"gpr s5 .64 168 0\n"
"gpr s6 .64 176 0\n"
"gpr s7 .64 184 0\n"
"gpr t8 .64 192 0\n"
"gpr t9 .64 200 0\n"
"gpr k0 .64 208 0\n"
"gpr k1 .64 216 0\n"
"gpr gp .64 224 0\n"
"gpr sp .64 232 0\n"
"gpr fp .64 240 0\n"
"gpr ra .64 248 0\n"
"gpr pc .64 256 0\n"
"gpr hi .64 264 0\n"
"gpr lo .64 272 0\n"
"gpr t .64 280 0\n";
"gpr zero .64 ? 0\n"
"gpr at .64 8 0\n"
"gpr v0 .64 16 0\n"
"gpr v1 .64 24 0\n"
"gpr a0 .64 32 0\n"
"gpr a1 .64 40 0\n"
"gpr a2 .64 48 0\n"
"gpr a3 .64 56 0\n"
"gpr t0 .64 64 0\n"
"gpr t1 .64 72 0\n"
"gpr t2 .64 80 0\n"
"gpr t3 .64 88 0\n"
"gpr t4 .64 96 0\n"
"gpr t5 .64 104 0\n"
"gpr t6 .64 112 0\n"
"gpr t7 .64 120 0\n"
"gpr s0 .64 128 0\n"
"gpr s1 .64 136 0\n"
"gpr s2 .64 144 0\n"
"gpr s3 .64 152 0\n"
"gpr s4 .64 160 0\n"
"gpr s5 .64 168 0\n"
"gpr s6 .64 176 0\n"
"gpr s7 .64 184 0\n"
"gpr t8 .64 192 0\n"
"gpr t9 .64 200 0\n"
"gpr k0 .64 208 0\n"
"gpr k1 .64 216 0\n"
"gpr gp .64 224 0\n"
"gpr sp .64 232 0\n"
"gpr fp .64 240 0\n"
"gpr ra .64 248 0\n"
"gpr lo .64 256 0\n"
"gpr hi .64 264 0\n"
"gpr pc .64 272 0\n"
"gpr badvaddr .64 280 0\n"
"gpr status .64 288 0\n"
"gpr cause .64 296 0\n"
"fpu f0 .64 304 0\n"
"fpu f1 .64 312 0\n"
"fpu f2 .64 320 0\n"
"fpu f3 .64 328 0\n"
"fpu f4 .64 336 0\n"
"fpu f5 .64 344 0\n"
"fpu f6 .64 352 0\n"
"fpu f7 .64 360 0\n"
"fpu f8 .64 368 0\n"
"fpu f9 .64 376 0\n"
"fpu f10 .64 384 0\n"
"fpu f11 .64 392 0\n"
"fpu f12 .64 400 0\n"
"fpu f13 .64 408 0\n"
"fpu f14 .64 416 0\n"
"fpu f15 .64 424 0\n"
"fpu f16 .64 432 0\n"
"fpu f17 .64 440 0\n"
"fpu f18 .64 448 0\n"
"fpu f19 .64 456 0\n"
"fpu f20 .64 464 0\n"
"fpu f21 .64 472 0\n"
"fpu f22 .64 480 0\n"
"fpu f23 .64 488 0\n"
"fpu f24 .64 496 0\n"
"fpu f25 .64 504 0\n"
"fpu f26 .64 512 0\n"
"fpu f27 .64 520 0\n"
"fpu f28 .64 528 0\n"
"fpu f29 .64 536 0\n"
"fpu f30 .64 544 0\n"
"fpu f31 .64 552 0\n"
"fpu fcsr .32 560 0\n" // 32 bit long
"fpu fir .32 564 0\n" // 32 bit long
"fpu restart .64 568 0\n"
"gpr t .64 576 0\n";
break;
}
return rz_str_dup(p);

View file

@ -8,6 +8,8 @@
#define ROUND_UP_4(x) ((x) + (4 - 1)) / 4 * 4
#define FP_LAYOUT 0x10
#define X86 0
#define X86_64 1
#define ARM 2
@ -21,9 +23,14 @@
// They are only for registers and store no other information.
#define OPENBSD_SPARC_V9 7
#define OPENBSD_SPARC_V9_FP (FP_LAYOUT | OPENBSD_SPARC_V9)
// MIPS related constants.
// The size of the pr status depends on the ABI
#define MIPS_32 8
#define MIPS_64 9
#define MIPS_FP32 (FP_LAYOUT | MIPS_32)
#define MIPS_FP64 (FP_LAYOUT | MIPS_64)
// Floating point register layout.
#define FP_LAYOUT 0x10
#define ARCH_LEN (FP_LAYOUT | 0xf)
#define ARCH_LEN (FP_LAYOUT | 0xf)
// See elf.c::elfcore_grok_solaris_note_impl() of binutil's bfd
// https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elf.c;h=6ef603010918f14eda69f0d0dc1637b4d51e8157;hb=HEAD#l11777
@ -93,6 +100,16 @@
#define SPARC32_PR_STATUS_REG_OFFSET_SP (4 * 14)
#define SPARC64_PR_STATUS_REG_OFFSET_SP (8 * 14)
// MIPS number of registers.
#define MIPS_N_GPR_REGS 45
#define MIPS_N_FP_REGS 33
#define MIPS32_REGS_SIZE (4 * MIPS_N_GPR_REGS) // int32
#define MIPS64_REGS_SIZE (8 * MIPS_N_GPR_REGS) // int64
#define MIPS_FP32_REGS_SIZE (4 * MIPS_N_FP_REGS) // float32
#define MIPS_FP64_REGS_SIZE (8 * MIPS_N_FP_REGS) // float64
#define MIPS_GPR32_STATUS_OFFSET (96)
#define MIPS_GPR64_STATUS_OFFSET (112)
static RzBinElfPrStatusLayout prstatus_layouts[ARCH_LEN] = {
[X86] = { 160, 0x48, 32, 0x3c },
[X86_64] = { 216, 0x70, 64, 0x98 },
@ -104,9 +121,15 @@ static RzBinElfPrStatusLayout prstatus_layouts[ARCH_LEN] = {
[SPARC_V9] = { SPARC64_REGS_SIZE, SPARC64_PR_STATUS_REG_OFFSET, 64, SPARC64_PR_STATUS_REG_OFFSET_SP },
[OPENBSD_SPARC_V9] = { SPARC64_REGS_SIZE, SPARC64_OPENBSD_REG_OFFSET, 64, SPARC64_PR_STATUS_REG_OFFSET_SP },
[MIPS_32] = { MIPS32_REGS_SIZE, MIPS_GPR32_STATUS_OFFSET, 0, 0 },
[MIPS_64] = { MIPS64_REGS_SIZE, MIPS_GPR64_STATUS_OFFSET, 0, 0 },
[SPARC32_FP] = { SPARC32_FPREGS_SIZE, SPARC32_FPREG_OFFSET, 0, 0 },
[SPARC64_FP] = { SPARC64_FPREGS_SIZE, SPARC32_FPREG_OFFSET, 0, 0 },
[OPENBSD_SPARC_V9_FP] = { SPARC64_OPENBSD_FPREGS_SIZE, SPARC64_OPENBSD_FPREG_OFFSET, 0, 0 },
[MIPS_FP32] = { MIPS_FP32_REGS_SIZE, 4, 0, 0 },
[MIPS_FP64] = { MIPS_FP64_REGS_SIZE, 8, 0, 0 },
};
static bool parse_register_note(ELFOBJ *bin, RzVector /*<RzBinElfNote>*/ *notes, Elf_(Nhdr) * note_segment_header, ut64 offset, size_t n_type) {
@ -310,6 +333,14 @@ static void note_segment_free(void *e, RZ_UNUSED void *user) {
rz_vector_fini(ptr);
}
static const size_t elf_get_prstatus_layout_mips(const ELFOBJ *bin, bool is_fp) {
size_t fp = is_fp ? FP_LAYOUT : 0;
if (bin->ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
return fp | MIPS_64;
}
return fp | MIPS_32;
}
RZ_BORROW RzBinElfPrStatusLayout *Elf_(rz_bin_elf_get_prstatus_layout)(RZ_NONNULL ELFOBJ *bin) {
rz_return_val_if_fail(bin, NULL);
@ -328,6 +359,12 @@ RZ_BORROW RzBinElfPrStatusLayout *Elf_(rz_bin_elf_get_prstatus_layout)(RZ_NONNUL
return prstatus_layouts + SPARC_V8PLUS;
case EM_SPARCV9:
return prstatus_layouts + SPARC_V9;
case EM_MIPS:
/* fall-thru */
case EM_MIPS_RS3_LE:
/* fall-thru */
case EM_MIPS_X:
return prstatus_layouts + elf_get_prstatus_layout_mips(bin, false);
}
return NULL;
@ -352,6 +389,18 @@ RZ_BORROW RzBinElfPrStatusLayout *Elf_(rz_bin_elf_get_regset_layout)(RZ_NONNULL
switch (bin->ehdr.e_machine) {
default:
return NULL;
case EM_MIPS:
/* fall-thru */
case EM_MIPS_RS3_LE:
/* fall-thru */
case EM_MIPS_X:
if (n_type == NT_FPREGSET) {
off = elf_get_prstatus_layout_mips(bin, true);
} else {
rz_warn_if_reached();
return NULL;
}
break;
case EM_SPARC:
if (n_type == NT_FPREGSET) {
off = FP_LAYOUT | SPARC;

View file

@ -101,9 +101,12 @@ gp = 0x00000000
sp = 0x00000000
fp = 0x00000000
ra = 0x00000000
pc = 0x00000000
hi = 0x00000000
lo = 0x00000000
hi = 0x00000000
pc = 0x00000000
badvaddr = 0x00000000
status = 0x00000000
cause = 0x00000000
t = 0x00000000
EOF
RUN
@ -145,9 +148,12 @@ gp = 0x0000000000000000
sp = 0x0000000000000000
fp = 0x0000000000000000
ra = 0x0000000000000000
pc = 0x0000000000000000
hi = 0x0000000000000000
lo = 0x0000000000000000
hi = 0x0000000000000000
pc = 0x0000000000000000
badvaddr = 0x0000000000000000
status = 0x0000000000000000
cause = 0x0000000000000000
t = 0x0000000000000000
EOF
RUN

View file

@ -821,52 +821,6 @@ EXPECT=<<EOF
EOF
RUN
NAME=mips regs
FILE==
CMDS=<<EOF
e asm.arch=mips
ar
EOF
EXPECT=<<EOF
zero = 0x00000000
at = 0x00000000
v0 = 0x00000000
v1 = 0x00000000
a0 = 0x00000000
a1 = 0x00000000
a2 = 0x00000000
a3 = 0x00000000
t0 = 0x00000000
t1 = 0x00000000
t2 = 0x00000000
t3 = 0x00000000
t4 = 0x00000000
t5 = 0x00000000
t6 = 0x00000000
t7 = 0x00000000
s0 = 0x00000000
s1 = 0x00000000
s2 = 0x00000000
s3 = 0x00000000
s4 = 0x00000000
s5 = 0x00000000
s6 = 0x00000000
s7 = 0x00000000
t8 = 0x00000000
t9 = 0x00000000
k0 = 0x00000000
k1 = 0x00000000
gp = 0x00000000
sp = 0x00000000
fp = 0x00000000
ra = 0x00000000
pc = 0x00000000
hi = 0x00000000
lo = 0x00000000
t = 0x00000000
EOF
RUN
NAME=mips sp/bp tracking
FILE=bins/elf/vars-mips-bp
ARGS=-e bin.dbginfo=0

View file

@ -505,3 +505,99 @@ fsr = 0x0000000000000000
EOF
EXPECT_ERR=
RUN
NAME=core regs linux mipsel
FILE=bins/elf/core/core-linux-mips32el-bin-ls
CMDS=<<EOF
ar
EOF
EXPECT=<<EOF
zero = 0x00000000
at = 0x824dd370
v0 = 0xffffffff
v1 = 0xffffffff
a0 = 0x555922d0
a1 = 0x55592350
a2 = 0xffffffff
a3 = 0x00000000
t0 = 0x00000000
t1 = 0x8214ad88
t2 = 0x8242de00
t3 = 0xffffffff
t4 = 0x00000000
t5 = 0x77f68e20
t6 = 0x00000000
t7 = 0x77f68e20
s0 = 0x555922d0
s1 = 0x55592190
s2 = 0x00000000
s3 = 0x7fffcbac
s4 = 0x7fffcbb0
s5 = 0xffffffff
s6 = 0x77ffbf04
s7 = 0x00000000
t8 = 0x00000000
t9 = 0x77e33978
k0 = 0x55592190
k1 = 0x00000000
gp = 0x77fb8050
sp = 0x7fffcb90
fp = 0x00000000
ra = 0x77f7ef54
lo = 0x0000000c
hi = 0x00000008
pc = 0x77e33978
badvaddr = 0x77dff180
status = 0x0000a413
cause = 0x10800024
t = 0x00000000
EOF
RUN
NAME=core regs linux mips64el
FILE=bins/elf/core/core-linux-mips64le-bin-ls
CMDS=<<EOF
ar
EOF
EXPECT=<<EOF
zero = 0x0000000000000000
at = 0xffffffff82588dac
v0 = 0xffffffffffffffff
v1 = 0xffffffffffffffff
a0 = 0x000000aaaaae2480
a1 = 0xffffffffffffffff
a2 = 0x0000000000000400
a3 = 0x0000000000000000
t0 = 0xfefefefefefefeff
t1 = 0x0000000000000001
t2 = 0x7373737373737373
t3 = 0xffffffffffffffff
t4 = 0x0000000000000000
t5 = 0xffffffff84080018
t6 = 0xffffffff824d85f0
t7 = 0x0000000074786509
s0 = 0x000000aaaaae2480
s1 = 0x000000aaaaae22a0
s2 = 0x0000000000000000
s3 = 0x000000ffffffca10
s4 = 0x000000ffffffca08
s5 = 0xffffffffffffffff
s6 = 0x000000fff7ffae68
s7 = 0x0000000000000000
t8 = 0x0000000000000012
t9 = 0x000000fff7e1d010
k0 = 0x000000aaaaae22a0
k1 = 0x0000000000000000
gp = 0x000000fff7fb8060
sp = 0x000000ffffffca00
fp = 0x0000000000000000
ra = 0x000000fff7f80938
lo = 0x0000000000000007
hi = 0x0000000000000000
pc = 0x000000fff7e1d010
badvaddr = 0x000000fff7f55c28
status = 0x000000000000a4f3
cause = 0x0000000010800024
t = 0x0000000000000000
EOF
RUN