blob: 3b8b2e352ed35f9307e1a935ff135624515fc15d [file] [log] [blame]
nethercotee65e47b2004-10-14 08:38:06 +00001#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
nethercote1aec0322004-10-14 08:52:43 +000013//-------------------------------------------------------------------
14// Test foreach_map()
15//-------------------------------------------------------------------
16
17static int x;
18
19static int f(char *start, char *end, const char *perm, off_t off,
20 int maj, int min, int ino, void* dummy) {
21 // Just do some nonsense action with each of the values so that Memcheck
22 // checks that they are valid.
23 x = ( start == 0 ? 0 : 1 );
24 x = ( end == 0 ? 0 : 1 );
25 x = ( perm == 0 ? 0 : 1 );
26 x = ( off == 0 ? 0 : 1 );
27 x = ( maj == 0 ? 0 : 1 );
28 x = ( min == 0 ? 0 : 1 );
29 x = ( ino == 0 ? 0 : 1 );
30 x = ( dummy == 0 ? 0 : 1 );
31
32 return /*True*/1;
33}
34
35static void test__foreach_map(void)
36{
37 fprintf(stderr, "Calling foreach_map()\n");
38 foreach_map(f, /*dummy*/NULL);
39}
40
41//-------------------------------------------------------------------
42// Test do_exec()
43//-------------------------------------------------------------------
44
nethercotee65e47b2004-10-14 08:38:06 +000045static void push_auxv(unsigned char **espp, int type, void *val)
46{
47 struct ume_auxv *auxp = (struct ume_auxv *)*espp;
48 auxp--;
49 auxp->a_type = type;
50 auxp->u.a_ptr = val;
51 *espp = (unsigned char *)auxp;
52}
53
54static void push(unsigned char **espp, void *v)
55{
56 void **vp = *(void ***)espp;
57 *--vp = v;
58 *espp = (unsigned char *)vp;
59}
60
nethercote1aec0322004-10-14 08:52:43 +000061static void test__do_exec(void)
nethercotee65e47b2004-10-14 08:38:06 +000062{
63 struct exeinfo info;
64 int err;
65 unsigned char* newstack;
66 unsigned char *esp;
67
68 info.argv = NULL;
69 info.exe_base = 0x50000000;
70 info.exe_end = 0x50ffffff;
71 info.map_base = 0x51000000;
72
nethercote1aec0322004-10-14 08:52:43 +000073 fprintf(stderr, "Calling do_exec(\"hello\")\n");
nethercotee65e47b2004-10-14 08:38:06 +000074 err = do_exec("hello", &info);
75 assert(0 == err);
76
77// printf("info.exe_base=%p exe_end=%p\n",
78// (void*)info.exe_base, (void*)info.exe_end);
79
80 newstack = malloc(STKSZ);
81 assert(0 != newstack);
82
83 esp = newstack+STKSZ;
84
85 /*
86 Set the new executable's stack up like the kernel would after
87 exec.
88
89 These are being pushed onto the stack, towards decreasing
90 addresses.
91 */
92 push_auxv(&esp, AT_NULL, 0); // auxv terminator
93 push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */
94 push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so
95 push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped
96 push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them
97
98 push(&esp, 0); /* no env */
99 push(&esp, 0); /* no argv */
100 push(&esp, 0); /* argc=0 */
101
102// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp);
103
104 jmp_with_stack(info.init_eip, (addr_t)esp);
105
nethercote1aec0322004-10-14 08:52:43 +0000106 assert(0); // UNREACHABLE
107}
108
109int main(void)
110{
111 test__foreach_map();
112 test__do_exec();
113
nethercotee65e47b2004-10-14 08:38:06 +0000114 return 0;
115}