blob: 458f6f0b9fc0df4b0f9eaffa1df8d45a912ab5df [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//-------------------------------------------------------------------
nethercote543a63f2004-10-14 09:28:11 +000042// Test find_auxv()
43//-------------------------------------------------------------------
44
45static void test__find_auxv(void)
46{
47 struct ume_auxv *auxv;
48
49 assert(ume_exec_esp != NULL);
50
51 fprintf(stderr, "Calling find_auxv()\n");
52 auxv = find_auxv((int*)ume_exec_esp);
53
54 // Check the auxv value looks sane
55 assert((void*)auxv > (void*)ume_exec_esp);
56 assert((unsigned int)auxv - (unsigned int)ume_exec_esp < 0x10000);
57
58 // Scan the auxv, check it looks sane
59 for (; auxv->a_type != AT_NULL; auxv++) {
60 switch(auxv->a_type) {
61 // Check a_type value looks like a plausible small constant
62 case 1 ... 64:
63 break;
64
65 default:
66 assert(0);
67 }
68 }
69}
70
71//-------------------------------------------------------------------
nethercote1aec0322004-10-14 08:52:43 +000072// Test do_exec()
73//-------------------------------------------------------------------
74
nethercotee65e47b2004-10-14 08:38:06 +000075static void push_auxv(unsigned char **espp, int type, void *val)
76{
77 struct ume_auxv *auxp = (struct ume_auxv *)*espp;
78 auxp--;
79 auxp->a_type = type;
80 auxp->u.a_ptr = val;
81 *espp = (unsigned char *)auxp;
82}
83
84static void push(unsigned char **espp, void *v)
85{
86 void **vp = *(void ***)espp;
87 *--vp = v;
88 *espp = (unsigned char *)vp;
89}
90
nethercote1aec0322004-10-14 08:52:43 +000091static void test__do_exec(void)
nethercotee65e47b2004-10-14 08:38:06 +000092{
93 struct exeinfo info;
94 int err;
95 unsigned char* newstack;
96 unsigned char *esp;
97
98 info.argv = NULL;
99 info.exe_base = 0x50000000;
100 info.exe_end = 0x50ffffff;
101 info.map_base = 0x51000000;
102
nethercote1aec0322004-10-14 08:52:43 +0000103 fprintf(stderr, "Calling do_exec(\"hello\")\n");
nethercotee65e47b2004-10-14 08:38:06 +0000104 err = do_exec("hello", &info);
105 assert(0 == err);
106
107// printf("info.exe_base=%p exe_end=%p\n",
108// (void*)info.exe_base, (void*)info.exe_end);
109
110 newstack = malloc(STKSZ);
111 assert(0 != newstack);
112
113 esp = newstack+STKSZ;
114
115 /*
116 Set the new executable's stack up like the kernel would after
117 exec.
118
119 These are being pushed onto the stack, towards decreasing
120 addresses.
121 */
122 push_auxv(&esp, AT_NULL, 0); // auxv terminator
123 push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */
124 push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so
125 push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped
126 push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them
127
128 push(&esp, 0); /* no env */
129 push(&esp, 0); /* no argv */
130 push(&esp, 0); /* argc=0 */
131
132// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp);
133
134 jmp_with_stack(info.init_eip, (addr_t)esp);
135
nethercote1aec0322004-10-14 08:52:43 +0000136 assert(0); // UNREACHABLE
137}
138
139int main(void)
140{
141 test__foreach_map();
nethercote543a63f2004-10-14 09:28:11 +0000142 test__find_auxv();
nethercote1aec0322004-10-14 08:52:43 +0000143 test__do_exec();
144
nethercotee65e47b2004-10-14 08:38:06 +0000145 return 0;
146}