blob: 84ca3910e14c098f3ddf0add21857387c3da5fa4 [file] [log] [blame]
nethercotee65e47b2004-10-14 08:38:06 +00001#define ELFSZ 32
2
nethercotec25c4492004-10-18 11:52:17 +00003// This file is a unit self-test for ume.c, jmp_with_stack.c
nethercotee65e47b2004-10-14 08:38:06 +00004
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
nethercotec25c4492004-10-18 11:52:17 +000013static void* init_sp;
14
nethercote1aec0322004-10-14 08:52:43 +000015//-------------------------------------------------------------------
16// Test foreach_map()
17//-------------------------------------------------------------------
18
nethercotec25c4492004-10-18 11:52:17 +000019static int x[8];
nethercote1aec0322004-10-14 08:52:43 +000020
21static int f(char *start, char *end, const char *perm, off_t off,
22 int maj, int min, int ino, void* dummy) {
23 // Just do some nonsense action with each of the values so that Memcheck
24 // checks that they are valid.
nethercotec25c4492004-10-18 11:52:17 +000025 x[0] = ( start == 0 ? 0 : 1 );
26 x[1] = ( end == 0 ? 0 : 1 );
27 x[2] = ( perm == 0 ? 0 : 1 );
28 x[3] = ( off == 0 ? 0 : 1 );
29 x[4] = ( maj == 0 ? 0 : 1 );
30 x[5] = ( min == 0 ? 0 : 1 );
31 x[6] = ( ino == 0 ? 0 : 1 );
32 x[7] = ( dummy == 0 ? 0 : 1 );
nethercote1aec0322004-10-14 08:52:43 +000033
nethercotec25c4492004-10-18 11:52:17 +000034 return /*True*/1 + x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7];
nethercote1aec0322004-10-14 08:52:43 +000035}
36
37static void test__foreach_map(void)
38{
39 fprintf(stderr, "Calling foreach_map()\n");
40 foreach_map(f, /*dummy*/NULL);
41}
42
43//-------------------------------------------------------------------
nethercote543a63f2004-10-14 09:28:11 +000044// Test find_auxv()
45//-------------------------------------------------------------------
46
47static void test__find_auxv(void)
48{
49 struct ume_auxv *auxv;
50
nethercotec25c4492004-10-18 11:52:17 +000051 assert(init_sp != NULL);
nethercote543a63f2004-10-14 09:28:11 +000052
53 fprintf(stderr, "Calling find_auxv()\n");
nethercotec25c4492004-10-18 11:52:17 +000054 auxv = find_auxv((int*)init_sp);
nethercote543a63f2004-10-14 09:28:11 +000055
56 // Check the auxv value looks sane
nethercotec25c4492004-10-18 11:52:17 +000057 assert((void*)auxv > (void*)init_sp);
58 assert((unsigned int)auxv - (unsigned int)init_sp < 0x10000);
nethercote543a63f2004-10-14 09:28:11 +000059
60 // Scan the auxv, check it looks sane
61 for (; auxv->a_type != AT_NULL; auxv++) {
62 switch(auxv->a_type) {
63 // Check a_type value looks like a plausible small constant
64 case 1 ... 64:
65 break;
66
67 default:
68 assert(0);
69 }
70 }
71}
72
73//-------------------------------------------------------------------
nethercote1aec0322004-10-14 08:52:43 +000074// Test do_exec()
75//-------------------------------------------------------------------
76
nethercotee65e47b2004-10-14 08:38:06 +000077static void push_auxv(unsigned char **espp, int type, void *val)
78{
79 struct ume_auxv *auxp = (struct ume_auxv *)*espp;
80 auxp--;
81 auxp->a_type = type;
82 auxp->u.a_ptr = val;
83 *espp = (unsigned char *)auxp;
84}
85
86static void push(unsigned char **espp, void *v)
87{
88 void **vp = *(void ***)espp;
89 *--vp = v;
90 *espp = (unsigned char *)vp;
91}
92
nethercote1aec0322004-10-14 08:52:43 +000093static void test__do_exec(void)
nethercotee65e47b2004-10-14 08:38:06 +000094{
95 struct exeinfo info;
96 int err;
97 unsigned char* newstack;
98 unsigned char *esp;
99
100 info.argv = NULL;
101 info.exe_base = 0x50000000;
102 info.exe_end = 0x50ffffff;
103 info.map_base = 0x51000000;
104
nethercote1aec0322004-10-14 08:52:43 +0000105 fprintf(stderr, "Calling do_exec(\"hello\")\n");
nethercotee65e47b2004-10-14 08:38:06 +0000106 err = do_exec("hello", &info);
107 assert(0 == err);
108
109// printf("info.exe_base=%p exe_end=%p\n",
110// (void*)info.exe_base, (void*)info.exe_end);
111
112 newstack = malloc(STKSZ);
113 assert(0 != newstack);
114
115 esp = newstack+STKSZ;
116
117 /*
118 Set the new executable's stack up like the kernel would after
119 exec.
120
121 These are being pushed onto the stack, towards decreasing
122 addresses.
123 */
124 push_auxv(&esp, AT_NULL, 0); // auxv terminator
125 push_auxv(&esp, AT_ENTRY, (void *)info.entry); // entrypoint of the main executable */
126 push_auxv(&esp, AT_BASE, (void *)info.interp_base); // base address of ld-linux.so
127 push_auxv(&esp, AT_PHDR, (void *)info.phdr); // where the ELF PHDRs are mapped
128 push_auxv(&esp, AT_PHNUM, (void*)info.phnum); // and how many of them
129
130 push(&esp, 0); /* no env */
131 push(&esp, 0); /* no argv */
132 push(&esp, 0); /* argc=0 */
133
134// fprintf(stderr, "ume_go: %p %p\n", (void*)info.init_eip, (void*)esp);
135
136 jmp_with_stack(info.init_eip, (addr_t)esp);
137
nethercote1aec0322004-10-14 08:52:43 +0000138 assert(0); // UNREACHABLE
139}
140
nethercotec25c4492004-10-18 11:52:17 +0000141int main(int argc, char** argv)
nethercote1aec0322004-10-14 08:52:43 +0000142{
nethercotec25c4492004-10-18 11:52:17 +0000143 init_sp = argv - 1;
144
nethercote1aec0322004-10-14 08:52:43 +0000145 test__foreach_map();
nethercote543a63f2004-10-14 09:28:11 +0000146 test__find_auxv();
nethercote1aec0322004-10-14 08:52:43 +0000147 test__do_exec();
148
nethercotee65e47b2004-10-14 08:38:06 +0000149 return 0;
150}