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