yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * crt0 for VAX |
| 3 | */ |
| 4 | |
| 5 | /* |
| 6 | * Program stack looks like: |
| 7 | * sp-> argc argument counter (integer) |
| 8 | * argv[0] program name (pointer) |
| 9 | * argv[1...N] program args (pointers) |
| 10 | * argv[argc-1] end of args (integer) |
| 11 | * NULL |
| 12 | * env[0...N] environment variables (pointers) |
| 13 | * NULL |
| 14 | */ |
| 15 | |
| 16 | #include <features.h> |
| 17 | |
| 18 | .text |
| 19 | .align 4 |
| 20 | |
| 21 | .global __start |
| 22 | __start: |
| 23 | .global _start |
| 24 | _start: |
| 25 | /* Kernel uses a_interp + 2, so __start isn't exactly CALLSed, */ |
| 26 | /* but we need to have two bytes here, so we use NOPs. This */ |
| 27 | /* won't hurt, though R0 would be invalid to push, but at */ |
| 28 | /* lease this looks like a real function. */ |
| 29 | .word 0x0101 |
| 30 | |
| 31 | movl $0, %fp /* FP = 0, since this is the */ |
| 32 | /* top-most stack frame */ |
| 33 | movl %sp, %r0 /* R0 = %sp */ |
| 34 | movl (%sp)+, %r4 /* R4 = argc */ |
| 35 | movl %sp, %r3 /* R3 = argv = &argv[0] */ |
| 36 | |
| 37 | #if (defined L_crt1 || defined L_gcrt1) && defined __UCLIBC_CTOR_DTOR__ |
| 38 | pushl %r0 /* stack_end */ |
| 39 | pushl $0 /* rtld_fini. This is probably needed for the */ |
| 40 | /* case where a dynamic linker is involved. So */ |
| 41 | /* this is an open FIXME that needs to be */ |
| 42 | /* addressed at some time... */ |
| 43 | pushl $_fini |
| 44 | pushl $_init |
| 45 | pushl %r3 /* Argument pointer */ |
| 46 | pushl %r4 /* And the argument count */ |
| 47 | pushl $main /* main() */ |
| 48 | |
| 49 | /* We need to call __uClibc_main which should not return. |
| 50 | * __uClibc_main (int (*main) (int, char **, char **), |
| 51 | * int argc, |
| 52 | * char **argv, |
| 53 | * void (*init) (void), |
| 54 | * void (*fini) (void), |
| 55 | * void (*rtld_fini) (void), |
| 56 | * void *stack_end); |
| 57 | */ |
| 58 | calls $7, __uClibc_main |
| 59 | #else /* FIXME: THIS IS BROKEN!!! */ |
| 60 | /* start to load the arguments from the stack */ |
| 61 | /* arguments are on ap stack */ |
| 62 | pushl %r2 |
| 63 | pushl %r3 |
| 64 | pushl %r4 |
| 65 | |
| 66 | calls $3, __uClibc_main |
| 67 | #endif |
| 68 | |
| 69 | /* The above __uClibc_start_main() shouldn't ever return. If it */ |
| 70 | /* does, we just crash. */ |
| 71 | halt |
| 72 | .align 2 |
| 73 | |