analysis: fix case range display in disassembly #5731)

* Fix disassembly bug related to case range labels
* Fix another edge case issue and tests
* Fix 2 more bugs causing case indices to get discarded instead of displayed
* Fix tests
This commit is contained in:
Anton Angelov 2026-01-07 17:56:22 +02:00 committed by GitHub
parent 797fcd0ff6
commit 7ebfa58fe2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 20 deletions

View file

@ -2214,7 +2214,8 @@ static void ds_show_flags(RzDisasmState *ds, bool overlapped) {
if (!strncmp(flag->name, "case.", 5)) {
sscanf(flag->name + 5, "%63[^.].%d", addr, &case_current);
ut64 saddr = rz_num_math(core->num, addr);
if (case_start == -1) {
bool switch_addr_changed = switch_addr != saddr;
if (case_start == -1 || switch_addr_changed) {
switch_addr = saddr;
case_prev = case_current;
case_start = case_current;
@ -2222,11 +2223,21 @@ static void ds_show_flags(RzDisasmState *ds, bool overlapped) {
continue;
}
}
if (case_current == case_prev + 1 && switch_addr == saddr) {
if ((case_current == case_prev + 1 || case_current == case_prev) && !switch_addr_changed) {
// We're still inside a range, continue extending the range boundary until we reach the
// end of the label list or a default label
case_prev = case_current;
bool next_is_default = false;
if (iter != uniqlist->tail) {
RzFlagItem *next_flag = rz_list_next(iter)->val;
next_is_default = !strncmp(next_flag->name + 5, "default", 7);
}
if (iter != uniqlist->tail && !next_is_default) {
continue;
}
} else if (!switch_addr_changed && iter == uniqlist->tail) {
// Iterate last index for a second time, otherwise the index will not get displayed
iter = rz_list_prev(iter);
}
}
if (printPre) {
@ -2311,7 +2322,7 @@ static void ds_show_flags(RzDisasmState *ds, bool overlapped) {
} else {
rz_cons_printf("%d:", case_prev);
}
if (iter != uniqlist->head && iter != uniqlist->tail) {
if (iter != uniqlist->head && iter != uniqlist->tail && case_current != case_prev) {
iter = rz_list_prev(iter);
}
case_start = case_current;
@ -2321,7 +2332,7 @@ static void ds_show_flags(RzDisasmState *ds, bool overlapped) {
} else {
rz_cons_printf("%s:", case_prev_name);
}
case_start = -1;
case_start = case_current;
}
}
case_prev = case_current;

View file

@ -2235,7 +2235,7 @@ EXPECT=<<EOF
..
| | ; CODE XREF from sym._Unwind_VRS_Get @ 0x78f4
| | ;-- case 1: ; from 0x78f4
| | ;-- case 4: ; from 0x78f4
| | ;-- case 3...4: ; from 0x78f4
| | 0x000078fe movs r0, 1
| ,==< 0x00007900 b 0x791c
| || ; CODE XREF from sym._Unwind_VRS_Get @ 0x78f4

View file

@ -3793,12 +3793,10 @@ EXPECT=<<EOF
;-- case 3...9: ; from 0x140001034
;-- case 12: ; from 0x140001034
;-- case 14: ; from 0x140001034
;-- case 18: ; from 0x140001034
;-- case 22...29: ; from 0x140001034
;-- case 31: ; from 0x140001034
;-- case 32...49: ; from 0x140001034
;-- case 51: ; from 0x140001034
;-- case 52...96: ; from 0x140001034
;-- case 17...18: ; from 0x140001034
;-- case 21...29: ; from 0x140001034
;-- case 31...49: ; from 0x140001034
;-- case 51...96: ; from 0x140001034
;-- case 98: ; from 0x140001034
EOF
RUN

View file

@ -327,37 +327,41 @@ EXPECT=<<EOF
| | 0x0800005e jmp rax ; switch table (116 cases) at 0x8001a34
| | ; CODE XREF from sym.owGetPageLength.constprop.0 @ 0x800005e
| | ;-- case 5: ; from 0x800005e
| | ;-- case 7: ; from 0x800005e
| | ;-- case 13...14: ; from 0x800005e
| | ;-- case 16: ; from 0x800005e
| | ;-- case 17: ; from 0x800005e
| | ;-- case 22...23: ; from 0x800005e
| | ;-- case 16...17: ; from 0x800005e
| | ;-- case 21...23: ; from 0x800005e
| | ;-- case 25: ; from 0x800005e
| | ;-- case 27...28: ; from 0x800005e
| | ;-- case 30: ; from 0x800005e
| | ;-- case 31...32: ; from 0x800005e
| | ;-- case 30...32: ; from 0x800005e
| | ;-- case 34: ; from 0x800005e
| | ;-- case 36...50: ; from 0x800005e
| | ;-- case 52: ; from 0x800005e
| | ;-- case 53...54: ; from 0x800005e
| | ;-- case 56: ; from 0x800005e
| | ;-- case 52...54: ; from 0x800005e
| | ;-- case 56...118: ; from 0x800005e
| | ;-- default: ; from 0x800005e
| `-> 0x08000060 xor eax, eax
| 0x08000062 ret
..
| ; CODE XREF from sym.owGetPageLength.constprop.0 @ 0x800005e
| ;-- case 4: ; from 0x800005e
| ;-- case 6: ; from 0x800005e
| ;-- case 8: ; from 0x800005e
| ;-- case 10: ; from 0x800005e
| ;-- case 12: ; from 0x800005e
| ;-- case 24: ; from 0x800005e
| ;-- case 26: ; from 0x800005e
| ;-- case 29: ; from 0x800005e
| ;-- case 33: ; from 0x800005e
| ;-- case 35: ; from 0x800005e
| 0x08000068 mov rsi, rdi ; arg1
| 0x0800006b mov edi, 0x01
| ,=< 0x08000070 jmp reloc.target.getPageLengthNV ; RELOC 32 getPageLengthNV
..
| | ; CODE XREF from sym.owGetPageLength.constprop.0 @ 0x800005e
| | ;-- case 9: ; from 0x800005e
| | ;-- case 11: ; from 0x800005e
| | ;-- case 15: ; from 0x800005e
| | ;-- case 19: ; from 0x800005e
| | ;-- case 18...19: ; from 0x800005e
| | 0x08000078 mov rsi, rdi ; arg1
| | 0x0800007b mov edi, 0x01
| ,==< 0x08000080 jmp reloc.target.getPageLengthEPROM ; RELOC 32 getPageLengthEPROM
@ -370,6 +374,7 @@ EXPECT=<<EOF
..
| ||| ; CODE XREF from sym.owGetPageLength.constprop.0 @ 0x800005e
| ||| ;-- case 55: ; from 0x800005e
| ||| ;-- case 119: ; from 0x800005e
| ||| 0x08000098 mov rsi, rdi ; arg1
| ||| 0x0800009b mov edi, 0x01
| ,====< 0x080000a0 jmp reloc.target.getPageLengthEE77 ; RELOC 32 getPageLengthEE77