movem exists in 2 symmetrical variants, register to memory (save to stack) and memory to register (pull from stack).
Per 68000 manual, when in word mode, increment (respectively decrement) is 2, and 4 in long mode.
For word mode, the various registers masks are handled by m2rfw0, r2mbw0, and r2mfw0.
This patch corrects the pointer increment for r2mbw0 to 2, aligning it to m2rfw0 and r2mfw0.
In ARM Thumb, function pointers are used with an offset. For example,
let's consider this C program:
static void fn(void) {}
__attribute__((noinline, optimize("O0")))
static void call_function(void (*callback)(void)) {
callback();
}
void call_fn_through_reference(void) {
call_function(fn);
}
Function call_fn_through_reference actually gives the address fn + 1 in
the first parameter of call_function, when this code is compiled in ARM
Thumb mode. In such a situation, Ghidra's decompiler produced:
void call_fn_through_reference(void)
{
call_function((void *)0x10189);
return;
}
The rules which were applied included both:
- rule constantptr, which converted the constant 0x10189 to
(#0x0 -> #0x10188) + #0x1 (opcodes PTRSUB and INT_ADD) ;
- rule ptrsubundo, which converted this expression to
(#0x0 + #0x10188) + #0x1 (later simplified to #0x10189).
The second rule cancelled the first one. In this case, rule ptrsubundo
should not be applied as the expression involving PTRSUB targets a valid
location.
Nevertheless, TypePointer::isPtrsubMatching(off=0x10188, extra=1, multiplier=0)
returned false. This is due to the fact that even though the size of
symbol fn was adjusted to be 2 (in method DecompileCallback::encodeFunction in
Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/DecompileCallback.java
), the actual type is "pointer to a TypeCode which size is 1", so
extra >= subType->getSize() and the method returned false.
Fix TypePointer::isPtrsubMatching to return true when a pointer to some
code is encountered with extra >= 0. This makes Ghidra's decompiler now
produce:
void call_fn_through_reference(void)
{
call_function(fn + 1);
return;
}
Fixes: https://github.com/NationalSecurityAgency/ghidra/issues/8471
Fixes: 34adcff830 ("GP-4782 Refactor RulePtrsubUndo")