blob: 275aa088c436db677d3ec530360c5a214605494e [file] [log] [blame]
jseward2886b0e2004-01-04 03:46:11 +00001
2/*
3 This file is part of Valgrind, an extensible x86 protected-mode
4 emulator for monitoring program execution on x86-Unixes.
5
6 Copyright (C) 2000-2004 Julian Seward
7 jseward@acm.org
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 02111-1307, USA.
23
24 The GNU General Public License is contained in the file COPYING.
25*/
26
fitzhardinge7e343cd2003-12-16 02:14:00 +000027#define _FILE_OFFSET_BITS 64
28
29#include <stdio.h>
30#include <elf.h>
31#include <string.h>
32#include <stdlib.h>
33#include <assert.h>
34#include <signal.h>
35#include <fcntl.h>
36#include <errno.h>
37
38#include "vg_include.h"
39
40#include "ume.h"
41#include "ume_arch.h"
42#include "ume_archdefs.h"
43
44static int stack[SIGSTKSZ*4];
45static int our_argc;
46
47/* Where we expect to find all our aux files (namely, stage2) */
48static const char *valgrind_lib = VG_LIBDIR;
49
50/* stage2's name */
51static const char stage2[] = "stage2";
52
53/* Modify the auxv the kernel gave us to make it look like we were
54 execed as the shared object.
55
56 This also inserts a new entry into the auxv table so we can
57 communicate some extra information to stage2 (namely, the fd of the
58 padding file, so it can identiry and remove the padding later).
59*/
60static void *fix_auxv(void *v_init_esp, const struct exeinfo *info)
61{
62 struct ume_auxv *auxv;
63 int *newesp;
64 int seen;
65 int delta;
66 int i;
67 static const int new_entries = 2;
68
69 /* make sure we're running on the private stack */
70 assert(&delta >= stack && &delta < &stack[sizeof(stack)/sizeof(*stack)]);
71
72 /* find the beginning of the AUXV table */
73 auxv = find_auxv(v_init_esp);
74
75 /* Work out how we should move things to make space for the new
76 auxv entry. It seems that ld.so wants a 16-byte aligned stack on
77 entry, so make sure that's the case. */
78 newesp = (int *)(((unsigned long)v_init_esp - new_entries * sizeof(*auxv)) & ~0xf);
79 delta = (char *)v_init_esp - (char *)newesp;
80
81 memmove(newesp, v_init_esp, (char *)auxv - (char *)v_init_esp);
82
83 v_init_esp = (void *)newesp;
84 auxv -= delta/sizeof(*auxv);
85
86 /* stage2 needs this so it can clean up the padding we leave in
87 place when we start it */
88 auxv[0].a_type = AT_UME_PADFD;
89 auxv[0].a_val = as_getpadfd();
90
91 /* This will be needed by valgrind itself so that it can
92 subsequently execve() children. This needs to be done here
93 because /proc/self/exe will go away once we unmap stage1. */
94 auxv[1].a_type = AT_UME_EXECFD;
95 auxv[1].a_val = open("/proc/self/exe", O_RDONLY);
96
97 /* make sure the rest are sane */
98 for(i = new_entries; i < delta/sizeof(*auxv); i++) {
99 auxv[i].a_type = AT_IGNORE;
100 auxv[i].a_val = 0;
101 }
102
103 /* OK, go through and patch up the auxv entries to match the new
104 executable */
105 seen = 0;
106 for(; auxv->a_type != AT_NULL; auxv++) {
107 if (0)
108 printf("doing auxv %p %4x: %d %p\n", auxv, auxv->a_type, auxv->a_val, auxv->a_ptr);
109
110 switch(auxv->a_type) {
111 case AT_PHDR:
112 seen |= 1;
113 auxv->a_val = info->phdr;
114 break;
115
116 case AT_PHNUM:
117 seen |= 2;
118 auxv->a_val = info->phnum;
119 break;
120
121 case AT_BASE:
122 seen |= 4;
123 auxv->a_val = info->interp_base;
124 break;
125
126 case AT_ENTRY:
127 seen |= 8;
128 auxv->a_val = info->entry;
129 break;
130 }
131 }
132
133 /* If we didn't see all the entries we need to fix up, then we
134 can't make the new executable viable. */
135 if (seen != 0xf) {
136 fprintf(stderr, "fix_auxv: we didn't see enough auxv entries (seen=%x)\n", seen);
137 exit(1);
138 }
139
140 return v_init_esp;
141}
142
143static void hoops(void)
144{
145 int err;
146 struct exeinfo info;
147 extern char _end;
148 int *esp;
149 char buf[strlen(valgrind_lib) + sizeof(stage2) + 16];
150
151 info.exe_base = PGROUNDUP(&_end);
152 info.exe_end = PGROUNDDN(ume_exec_esp);
153
154 /* XXX FIXME: how can stage1 know where stage2 wants things placed?
155 Options:
156 - we could look for a symbol
157 - it could have a special PHDR (v. ELF specific)
158 - something else?
159 */
160 info.map_base = 0xb0000000;
161 info.setbrk = 1; /* ask do_exec to move the brk-base */
162 info.argv = NULL;
163
fitzhardingea49f9b52003-12-16 22:26:45 +0000164 snprintf(buf, sizeof(buf), "%s/%s", valgrind_lib, stage2);
fitzhardinge7e343cd2003-12-16 02:14:00 +0000165
166 err = do_exec(buf, &info);
167
168 if (err != 0) {
169 fprintf(stderr, "failed to load %s: %s\n",
170 buf, strerror(err));
171 exit(1);
172 }
173
174 /* Make sure stage2's dynamic linker can't tromp on the lower part
175 of the address space. */
176 as_pad(0, (void *)info.map_base);
177
178 esp = fix_auxv(ume_exec_esp, &info);
179
180 if (0) {
181 int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
182 printf("mapping %10p-%10p %s %02x:%02x %d\n",
183 start, end, perm, maj, min, ino);
184 return 1;
185 }
186 printf("---------- launch stage 2 ----------\n");
187 printf("eip=%p esp=%p\n", (void *)info.init_eip, esp);
188 foreach_map(prmap);
189 }
190
191 ume_go(info.init_eip, (addr_t)esp);
192}
193
194int main(int argc, char **argv)
195{
196 const char *cp = getenv(VALGRINDLIB);
197
198 if (cp != NULL)
199 valgrind_lib = cp;
200
201 assert(ume_exec_esp != NULL);
202
203 our_argc = argc;
204
205 /* move onto another stack so we can play with the main one */
206 ume_go((addr_t)hoops, (addr_t)stack + sizeof(stack));
207}