-
Notifications
You must be signed in to change notification settings - Fork 83
Open
Labels
Description
Since there is no division instruction in ARM, the compiler tries to resolve it with a function, but when the function is defined with a function pointer, the compiler issues bl to the address of the function pointer in the data address. so it crashes by Prefetch abort excption.
Compile environment
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-q -Wall -O2 -fno-inline")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
set_target_properties(${PROJECT_NAME}
PROPERTIES LINK_FLAGS "-nostdlib"
COMPILE_FLAGS "-D__PSP2_USER__"
)
example
// 0x81000000 for text address
uint64_t test_div(uint64_t a, uint64_t b){
return a / b;
}
// 0x81001000 for text address
// __aeabi_uldivmod was get function pointer by somehow
uint64_t (* __aeabi_uldivmod)(uint64_t a, uint64_t b);
Compiling this (^) code will give you the following assembly
test_div:
push {lr}
bl #0x81001000
// and some...
pop {pc}
But the correct code is:
test_div:
push {ip, lr}
movw ip, #:lower16:__aeabi_uldivmod
movt ip, #:upper16:__aeabi_uldivmod
ldr ip, [ip]
blx ip
// and some...
pop {pc}
So for some reason we have to devise a definition for the compiler function.
Like
uint64_t __attribute__((noinline, naked)) __aeabi_uldivmod(uint64_t a, uint64_t b){
__asm__ volatile (
"push {ip, lr}\n"
"movw ip, #:lower16:___aeabi_uldivmod\n"
"movt ip, #:upper16:___aeabi_uldivmod\n"
"ldr ip, [ip]\n"
"blx ip\n"
"pop {ip, pc}\n"
:
:
:
);
}