Skip to content

The compiler bug for data address refer #205

@Princess-of-Sleeping

Description

@Princess-of-Sleeping

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"
		:
		:
		:
	);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions