Version and Platform (required):
- Binary Ninja Version: 5.4.9744-dev Ultimate, d7f134fd
- OS: macos 26.5.0
- CPU Architecture: arm64
Bug Description:
When changing a function of type int64_t GetPoint() __pure to have a return type of struct Point, the return value location remains fixed at __location("x0"), despite Point being too large to fit within x0. Since the return value location was originally inferred by analysis, updating the return type should cause it to be recomputed.
Steps To Reproduce:
- Open libtest.dylib from the attached zip file.
- Observe that
GetPoint looks like so:
| Disassembly | HLIL |
004002d0 int64_t GetPoint() __pure
004002d0 0 20078652 mov w0, #0x3039
004002d4 0 41268152 mov w1, #0x932
004002d8 0 2100a072 movk w1, #0x1, lsl #0x10 {0x10932}
004002dc 0 c0035fd6 ret
|
004002d0 int64_t GetPoint() __pure
004002dc return 0x3039
|
- Define a type
struct Point { uint64_t x, y; };.
- Change the return type of
GetPoint to Point.
GetPoint updates to look like so. Note the explicit __location("x0") override:
| Disassembly | HLIL |
004002d0 struct Point GetPoint() __location("x0") __pure
004002d0 0 20078652 mov w0, #0x3039
004002d4 0 41268152 mov w1, #0x932
004002d8 0 2100a072 movk w1, #0x1, lsl #0x10 {0x10932}
004002dc 0 c0035fd6 ret
|
004002d0 struct Point GetPoint() __location("x0") __pure
004002dc return 0x3039
|
- Use Edit Function Properties to change the return value's "source" from Custom to Default. Note that the location column updates to
x1:x0 when doing this.
GetPoint has now updated to have the expected HLIL:
| Disassembly | HLIL |
004002d0 struct Point GetPoint() __pure
004002d0 0 20078652 mov w0, #0x3039
004002d4 0 41268152 mov w1, #0x932
004002d8 0 2100a072 movk w1, #0x1, lsl #0x10 {0x10932}
004002dc 0 c0035fd6 ret
|
004002d0 struct Point GetPoint() __pure
004002d0 struct Point result
004002d0 result.x = 0x3039
004002d0 result.y = 0x10932
004002dc return result
|
Expected Behavior:
Changing the type in step 4 should be sufficient to update the return value location. It should not be necessary to explicitly reset the return value's "source" to Default since the user never explicitly changed it from Default.
Binary:
libtest.dylib.zip
Created via:
mrowe@quicksilver:~$ cat test.cpp
#include <stdint.h>
struct Point {
uint64_t x;
uint64_t y;
};
Point GetPoint()
{
return { 12345, 67890 };
}
mrowe@quicksilver:~$ cc -Os -shared -o libtest.dylib test.cpp
mrowe@quicksilver:~$
Version and Platform (required):
Bug Description:
When changing a function of type
int64_t GetPoint() __pureto have a return type ofstruct Point, the return value location remains fixed at__location("x0"), despitePointbeing too large to fit withinx0. Since the return value location was originally inferred by analysis, updating the return type should cause it to be recomputed.Steps To Reproduce:
GetPointlooks like so:struct Point { uint64_t x, y; };.GetPointtoPoint.GetPointupdates to look like so. Note the explicit__location("x0")override:x1:x0when doing this.GetPointhas now updated to have the expected HLIL:Expected Behavior:
Changing the type in step 4 should be sufficient to update the return value location. It should not be necessary to explicitly reset the return value's "source" to Default since the user never explicitly changed it from Default.
Binary:
libtest.dylib.zip
Created via: