1db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien#include <stdio.h> 2db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien#include <stdlib.h> 3db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien#include <stdint.h> 4db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 5db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 6db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien// Note: The first instruction stands for ldr, which loads the data from 7db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien// memory to the specified register. Notice that due to the pipeline design, 8db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien// when ldr is executed, the program will be advanced by 8. So, to get our 9db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien// address we should substract it by 4. 10db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 11db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chienuint32_t stub[] = { 12db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 0xe51ff004ul, // ldr pc, [pc, #-4] 13db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 0x00000000ul // address 14db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien}; 15db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 16db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chienint test() { 17db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien printf("hello world!\n"); 18db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien return 5; 19db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien} 20db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 21db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chienint main() { 22db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien int (*f)() = (int (*)())stub; 23db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien stub[1] = (uint32_t)(uintptr_t)test; 24db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien 25db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien printf("return = %d\n", f()); 26db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien return EXIT_SUCCESS; 27db8ee06e529a5d3034c6f3e7f2324d918d9834a1Logan Chien} 28