Improve ARM/AArch64 DATA xrefs analysis (#6506)

Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
NOT XVilka 2026-06-14 21:10:30 +08:00 committed by GitHub
parent 323e707114
commit f91ef729bf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 72 additions and 9 deletions

View file

@ -4010,6 +4010,43 @@ static bool addr_in_exec_section(RzBinObject *bo, ut64 addr) {
return sec && (sec->perm & RZ_PERM_X);
}
static bool addr_in_exec_segment(RzBinObject *bo, ut64 addr) {
RzBinSection *seg = rz_bin_get_segment_at(bo, addr, true);
return seg && (seg->perm & RZ_PERM_X);
}
/** \brief How a DATA xref's instruction relates to its target address. */
typedef enum {
XREF_REF_OTHER = 0, ///< address computation, control flow, etc. — handled as before
XREF_REF_MEM_ACCESS, ///< load/store of the target: an unambiguous data access
XREF_REF_COINCIDENTAL_IMM, ///< immediate equals the target with no data access (e.g. `sub sp, sp, 0x810`)
} XrefRefKind;
/** \brief Classify how the instruction at \p from references \p target. */
static XrefRefKind xref_ref_kind(RzCore *core, ut64 from, ut64 target) {
RzAnalysisOp *op = rz_core_analysis_op(core, from, RZ_ANALYSIS_OP_MASK_VAL);
if (!op) {
return XREF_REF_OTHER;
}
XrefRefKind kind = XREF_REF_OTHER;
switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
case RZ_ANALYSIS_OP_TYPE_LOAD:
case RZ_ANALYSIS_OP_TYPE_STORE:
kind = XREF_REF_MEM_ACCESS;
break;
case RZ_ANALYSIS_OP_TYPE_MOV:
case RZ_ANALYSIS_OP_TYPE_LEA:
break; // address into a register: leave to the heuristic below
default:
if (op->val == target) {
kind = XREF_REF_COINCIDENTAL_IMM;
}
break;
}
rz_analysis_op_free(op);
return kind;
}
static void analysis_mark_xrefs_as_data(RzCore *core) {
int bits = rz_asm_get_bits(core->rasm);
ut64 ptr_size = bits == 64 ? 8 : 4;
@ -4075,6 +4112,14 @@ static void analysis_mark_xrefs_as_data(RzCore *core) {
if (!bo) {
continue;
}
// Only executable-region targets need classifying: reject constants that merely
// equal a code address (e.g. `sub sp, sp, 0x810`), while skipping the decode for
// the common data-section case.
bool in_exec_segment = addr_in_exec_segment(bo, target);
XrefRefKind ref_kind = in_exec_segment ? xref_ref_kind(core, xref->from, target) : XREF_REF_OTHER;
if (ref_kind == XREF_REF_COINCIDENTAL_IMM) {
continue;
}
bool target_in_exec = addr_in_exec_section(bo, target);
if (target_in_exec) {
ut8 buf[8] = { 0 };
@ -4093,14 +4138,13 @@ static void analysis_mark_xrefs_as_data(RzCore *core) {
// stored value is a code pointer — skip
continue;
}
if (!val_sec) {
// address do not refer to a section in ELF
// A load/store marks the target directly, covering whole literal pools
// regardless of distance (e.g. K64F sym.poweroff entries at 0x11d4/0x11d8).
// Other refs keep the conservative heuristic: accept only padding right
// after the referencing function.
if (ref_kind != XREF_REF_MEM_ACCESS && !val_sec) {
ut64 fcn_end = fcn_from->addr + rz_analysis_function_linear_size(fcn_from);
if (target < fcn_end) {
continue;
}
// not padding
if (target - fcn_end >= ptr_size) {
if (target < fcn_end || target - fcn_end >= ptr_size) {
continue;
}
}

View file

@ -2305,6 +2305,8 @@ s 0x4e0
pd 1
s 0xd50
pd 1
s 0x11d0
pd 3
EOF
EXPECT=<<EOF
; DATA XREF from dbg.sched_run @ 0x490
@ -2313,5 +2315,14 @@ EXPECT=<<EOF
; DATA XREF from dbg.bit_clear8 @ 0xd34
;-- data.00000d50:
0x00000d50 .dword 0x01ffffe0
; DATA XREF from sym.poweroff @ 0x1192
;-- data.000011d0:
0x000011d0 .dword 0x00002744 ; spi_config ; obj.spi_config
; DATA XREF from sym.poweroff @ 0x11a0
;-- data.000011d4:
0x000011d4 .dword 0x4002d000
; DATA XREFS from sym.poweroff @ 0x11b6, 0x11c6
;-- data.000011d8:
0x000011d8 .dword 0x40047000
EOF
RUN

View file

@ -363,6 +363,9 @@ s 0xe080
pd 1
s 0xe09c
pd 1
e asm.xrefs=false
e asm.comments=false
pd 3 @ 0x810
EOF
EXPECT=<<EOF
; DATA XREFS from fcn.00005b80 @ 0x5bb0, 0x5bec
@ -375,5 +378,8 @@ EXPECT=<<EOF
0x0000e0ac 64ca ffff 28ca ffff c8ca ffff 0000 0000 d...(...........
0x0000e0bc 0000 0000 ....
0x00000810 ret
0x00000814 ldr x8, [x0]
0x00000818 add x9, x8, 1
EOF
RUN

View file

@ -11,13 +11,15 @@ EXPECT=<<EOF
0x0000043a 0000 (null)
; STRING XREFS from entry0 @ 0x40c, 0x410
;-- data.00000434:
0x00000434 lsrs r4, r1, 0xf
0x00000436 movs r1, r0
0x00000434 .dword 0x00010bcc
; DATA XREF from entry0 @ 0x414
;-- data.00000438:
0x00000438 .dword 0x00000020
; DATA XREF from entry0 @ 0x420
;-- data.0000043c:
0x0000043c .dword 0x00000030
; DATA XREF from entry0 @ 0x426
;-- data.00000440:
0x00000440 .dword 0x00000034
EOF
RUN