nethercote | e65e47b | 2004-10-14 08:38:06 +0000 | [diff] [blame^] | 1 | #define ELFSZ 32 |
| 2 | |
| 3 | // This file is a unit self-test for ume.c, ume_entry.c, jmp_with_stack.c |
| 4 | |
| 5 | #include <stdlib.h> |
| 6 | #include <stdio.h> |
| 7 | #include <assert.h> |
| 8 | #include <elf.h> |
| 9 | #include "../../coregrind/ume.h" |
| 10 | |
| 11 | #define STKSZ (64*1024) |
| 12 | |
| 13 | static void push_auxv(unsigned char **espp, int type, void *val) |
| 14 | { |
| 15 | struct ume_auxv *auxp = (struct ume_auxv *)*espp; |
| 16 | auxp--; |
| 17 | auxp->a_type = type; |
| 18 | auxp->u.a_ptr = val; |
| 19 | *espp = (unsigned char *)auxp; |
| 20 | } |
| 21 | |
| 22 | static void push(unsigned char **espp, void *v) |
| 23 | { |
| 24 | void **vp = *(void ***)espp; |
| 25 | *--vp = v; |
| 26 | *espp = (unsigned char *)vp; |
| 27 | } |
| 28 | |
| 29 | |
| 30 | int main(void) |
| 31 | { |
| 32 | struct exeinfo info; |
| 33 | int err; |
| 34 | unsigned char* newstack; |
| 35 | unsigned char *esp; |
| 36 | |
| 37 | info.argv = NULL; |
| 38 | info.exe_base = 0x50000000; |
| 39 | info.exe_end = 0x50ffffff; |
| 40 | info.map_base = 0x51000000; |
| 41 | |
| 42 | err = do_exec("hello", &info); |
| 43 | assert(0 == err); |
| 44 | |
| 45 | // printf("info.exe_base=%p exe_end=%p\n", |
| 46 | // (void*)info.exe_base, (void*)info.exe_end); |
| 47 | |
| 48 | newstack = malloc(STKSZ); |
| 49 | assert(0 != newstack); |
| 50 | |
| 51 | esp = newstack+STKSZ; |
| 52 | |
| 53 | /* |
| 54 | Set the new executable's stack up like the kernel would after |
| 55 | exec. |
| 56 | |
| 57 | These are being pushed onto the stack, towards decreasing |
| 58 | addresses. |
| 59 | */ |
| 60 | push_auxv(&esp, AT_NULL, 0); // auxv terminator |
| 61 | push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */ |
| 62 | push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so |
| 63 | push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped |
| 64 | push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them |
| 65 | |
| 66 | push(&esp, 0); /* no env */ |
| 67 | push(&esp, 0); /* no argv */ |
| 68 | push(&esp, 0); /* argc=0 */ |
| 69 | |
| 70 | // fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp); |
| 71 | |
| 72 | jmp_with_stack(info.init_eip, (addr_t)esp); |
| 73 | |
| 74 | return 0; |
| 75 | } |