Skip to content

Fix the drifted table-position dispatch in the PowerPC pseudo filter ##arch - #26355

Open
phix33 wants to merge 3 commits into
radareorg:masterfrom
phix33:ppc-pseudo-index-magic
Open

Fix the drifted table-position dispatch in the PowerPC pseudo filter ##arch#26355
phix33 wants to merge 3 commits into
radareorg:masterfrom
phix33:ppc-pseudo-index-magic

Conversation

@phix33

@phix33 phix33 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator
  • Mark this if you consider it ready to merge
  • I've added tests (optional)
  • I wrote some lines in the book (optional)

Description

replace() applied three special cases by hardcoded ops[] position: implicit cr0 for cmp/branch, the trap TO code, and the SPR name lookup. Three .-suffixed rows (rlwimi., rlwinm., rlwnm.) were added later without bumping those numbers, so the last two guards pointed 3 rows too early:

rlwnm r3, r4, r5, 6, 7  ->  ? = rol32(r4, r5) & 0x3000000
twi 5, r3, 0            ->  if ((word) mq 5 (word) 0) trap
mfspr r3, 0x110         ->  r3 = 0x110

The rotate destination was fed through the TO decoder, twi's operand through getspr() (strtol ("r3", NULL, 16) == 0 -> SPR_MQ), and mfspr/mtspr never reached the SPR lookup at all. These now dispatch on the mnemonic, like the mask fixups already do in the same function; the stale //0..//45 comments go with them.

Two bugs found while doing that ride along as separate commits:

  • rldicr took rldic's mask — !strncmp (argv[0], "rldic", 5) is tested before the rldicr arm, leaving that arm dead.
  • The trap block parsed the TO code with atoi, but capstone prints TO >= 10 in hex, so switch cases 12 and 20 were unreachable. Relatedly tdu/tdui/twu/ twui are TO=31-folded 2-operand mnemonics that carried 3-operand templates.

Four tests in db/cmd/cmd_pseudo_ppc, each confirmed failing before its fix.

@trufae

trufae commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

mq? twi 5, r3, 0 -> if ((word) mq 5 (word) 0) trap

also, conflicts after merging your other pr

@trufae

trufae commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

these two functions can be much shorter:

// cmp* and the cr0 conditional branches: b{eq,ge,gt,le,lt,ne} with an optional +/- hint
static bool op_needs_cr0(const char *op) {
	if (r_str_startswith (op, "cmp")) {
		return true;
	}
	if (op[0] != 'b' || !op[1] || !op[2] || (op[3] && (op[4] || !strchr ("+-", op[3])))) {
		return false;
	}
	const char cond[] = { op[1], op[2], 0 };
	return strstr ("eq ge gt le lt ne", cond) != NULL;
}

// only td/tdi/tw/twi carry a TO code operand, every named form (tweq, tdlgt, tdu..) encodes it in the mnemonic
static bool op_is_trap(const char *op) {
	return !strcmp (op, "td") || !strcmp (op, "tdi") || !strcmp (op, "tw") || !strcmp (op, "twi");
}

@trufae

trufae commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

also change all the strncmps with custom lentghs for just r_str_starts:

						} else if (letter == 4 && !strncmp (argv[0], "rlwimi", 6)) {

@trufae

trufae commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

in other words pick this commit: dfe2c40

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants