|
From: <sv...@va...> - 2005-08-08 20:38:25
|
Author: sewardj
Date: 2005-08-08 20:49:58 +0100 (Mon, 08 Aug 2005)
New Revision: 4349
Log:
Not needed in the new direct-start static linking scheme.
Removed:
branches/ASPACEM/coregrind/stage1.c
Deleted: branches/ASPACEM/coregrind/stage1.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/stage1.c 2005-08-08 19:47:43 UTC (rev 4348=
)
+++ branches/ASPACEM/coregrind/stage1.c 2005-08-08 19:49:58 UTC (rev 4349=
)
@@ -1,372 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Startup: preliminaries stage1.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Julian Seward=20
- js...@ac...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#define _FILE_OFFSET_BITS 64
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-#include "memcheck/memcheck.h"
-#include "pub_core_basics.h"
-#include "pub_core_debuglog.h"
-#include "pub_core_libcbase.h" // For VG_PGROUNDUP, VG_PGROUNDDN
-#include "pub_core_libcproc.h" // For VALGRINDLIB
-#include "pub_core_ume.h"
-
-
-static int stack[SIGSTKSZ*4];
-
-// Initial stack pointer, which points to argc.
-static void* init_sp;
-
-/* Where we expect to find all our aux files (namely, stage2) */
-static const char *valgrind_lib =3D VG_LIBDIR;
-
-/* stage2's name */
-static const char stage2[] =3D "stage2";
-
-/*------------------------------------------------------------*/
-/*--- Auxv modification ---*/
-/*------------------------------------------------------------*/
-
-/* Modify the auxv the kernel gave us to make it look like we were
- execed as the shared object.
-
- This also inserts a new entry into the auxv table so we can
- communicate some extra information to stage2 (namely, the fd of the
- padding file, so it can identiry and remove the padding later).
-*/
-static void *fix_auxv(void *v_init_esp, const struct exeinfo *info,
- int padfile)
-{
- struct ume_auxv *auxv;
- int *newesp;
- int seen;
- int delta;
- int i;
- static const int new_entries =3D 2;
-
- /* make sure we're running on the private stack */
- assert(&delta >=3D stack && &delta < &stack[sizeof(stack)/sizeof(*sta=
ck)]);
- =20
- /* find the beginning of the AUXV table */
- auxv =3D VG_(find_auxv)(v_init_esp);
-
- /* Work out how we should move things to make space for the new
- auxv entry. It seems that ld.so wants a 16-byte aligned stack on
- entry, so make sure that's the case. */
- newesp =3D (int *)(((unsigned long)v_init_esp - new_entries * sizeof(=
*auxv)) & ~0xf);
- delta =3D (char *)v_init_esp - (char *)newesp;
-
- memmove(newesp, v_init_esp, (char *)auxv - (char *)v_init_esp);
- =20
- v_init_esp =3D (void *)newesp;
- auxv -=3D delta/sizeof(*auxv);
-
- /* stage2 needs this so it can clean up the padding we leave in
- place when we start it */
- auxv[0].a_type =3D AT_UME_PADFD;
- auxv[0].u.a_val =3D padfile;
-
- /* This will be needed by valgrind itself so that it can
- subsequently execve() children. This needs to be done here
- because /proc/self/exe will go away once we unmap stage1. */
- auxv[1].a_type =3D AT_UME_EXECFD;
- auxv[1].u.a_val =3D open("/proc/self/exe", O_RDONLY);
-
- /* make sure the rest are sane */
- for(i =3D new_entries; i < delta/sizeof(*auxv); i++) {
- auxv[i].a_type =3D AT_IGNORE;
- auxv[i].u.a_val =3D 0;
- }
-
- /* OK, go through and patch up the auxv entries to match the new
- executable */
- seen =3D 0;
- for(; auxv->a_type !=3D AT_NULL; auxv++) {
- if (0)
- printf("doing auxv %p %5lld: %lld %p\n",
- auxv, (Long)auxv->a_type, (Long)auxv->u.a_val, auxv->u.a=
_ptr);
-
- switch(auxv->a_type) {
- case AT_PHDR:
- seen |=3D 1;
- auxv->u.a_val =3D info->phdr;
- break;
-
- case AT_PHNUM:
- seen |=3D 2;
- auxv->u.a_val =3D info->phnum;
- break;
-
- case AT_BASE:
- seen |=3D 4;
- auxv->u.a_val =3D info->interp_base;
- break;
-
- case AT_ENTRY:
- seen |=3D 8;
- auxv->u.a_val =3D info->entry;
- break;
-
-#if (defined(AT_SYSINFO) || defined(AT_SYSINFO_EHDR))
-#ifdef AT_SYSINFO
- case AT_SYSINFO:
-#endif
-#ifdef AT_SYSINFO_EHDR
- case AT_SYSINFO_EHDR:
-#endif
- auxv->a_type =3D AT_IGNORE;
- break;
-#endif
- }
- }
-
- /* If we didn't see all the entries we need to fix up, then we
- can't make the new executable viable. */
- if (seen !=3D 0xf) {
- fprintf(stderr, "valgrind: we didn't see enough auxv entries (seen=
=3D%x)\n", seen);
- exit(1);
- }
-
- return v_init_esp;
-}
-
-
-/*------------------------------------------------------------*/
-/*--- Address space padding ---*/
-/*------------------------------------------------------------*/
-
-static void check_mmap(void* res, void* base, int len)
-{
- if ((void*)-1 =3D=3D res) {
- fprintf(stderr, "valgrind: padding mmap(%p, %d) failed during star=
tup.\n"
- "valgrind: is there a hard virtual memory limit se=
t?\n",
- base, len);
- exit(1);
- }
-}
-
-typedef struct {
- char* fillgap_start;
- char* fillgap_end;
- int fillgap_padfile;
-} fillgap_extra;
-
-static int fillgap(char *segstart, char *segend, const char *perm, off_t=
off,=20
- int maj, int min, int ino, void* e)
-{
- fillgap_extra* extra =3D e;
-
- if (segstart >=3D extra->fillgap_end)
- return 0;
-
- if (segstart > extra->fillgap_start) {
- void* res =3D mmap(extra->fillgap_start, segstart - extra->fillgap=
_start,
- PROT_NONE, MAP_FIXED|MAP_PRIVATE,=20
- extra->fillgap_padfile, 0);
- check_mmap(res, extra->fillgap_start, segstart - extra->fillgap_st=
art);
- }
- extra->fillgap_start =3D segend;
- =20
- return 1;
-}
-
-// Choose a name for the padfile, open it.
-static=20
-int as_openpadfile(void)
-{
- char buf[256];
- int padfile;
- int seq =3D 1;
- do {
- snprintf(buf, 256, "/tmp/.pad.%d.%d", getpid(), seq++);
- padfile =3D open(buf, O_RDWR|O_CREAT|O_EXCL, 0);
- unlink(buf);
- if (padfile =3D=3D -1 && errno !=3D EEXIST) {
- fprintf(stderr, "valgrind: couldn't open padfile\n");
- exit(44);
- }
- } while(padfile =3D=3D -1);
-
- return padfile;
-}
-
-// Pad all the empty spaces in a range of address space to stop interlop=
ers.
-static
-void as_pad(void *start, void *end, int padfile)
-{
- fillgap_extra extra;
- extra.fillgap_start =3D start;
- extra.fillgap_end =3D end;
- extra.fillgap_padfile =3D padfile;
-
- VG_(foreach_map)(fillgap, &extra);
-=09
- if (extra.fillgap_start < extra.fillgap_end) {
- void* res =3D mmap(extra.fillgap_start,=20
- extra.fillgap_end - extra.fillgap_start,
- PROT_NONE, MAP_FIXED|MAP_PRIVATE, padfile, 0);
- check_mmap(res, extra.fillgap_start,=20
- extra.fillgap_end - extra.fillgap_start);
- }
-}
-
-
-/*------------------------------------------------------------*/
-/*--- main() and related pieces ---*/
-/*------------------------------------------------------------*/
-
-static int prmap(char *start, char *end, const char *perm, off_t off, in=
t maj,
- int min, int ino, void* dummy) {
- printf("mapping %10p-%10p %s %02x:%02x %d\n",
- start, end, perm, maj, min, ino);
- return 1;
-}
-
-
-static void main2(void)
-{
- int err, padfile;
- struct exeinfo info;
- extern char _end;
- int *esp;
- char buf[strlen(valgrind_lib) + sizeof(stage2) + 16];
- info.exe_end =3D VG_PGROUNDDN(init_sp);
-#ifdef HAVE_PIE
- info.exe_base =3D VG_ROUNDDN(info.exe_end - 0x02000000, 0x10000000);
- assert(info.exe_base >=3D VG_PGROUNDUP(&_end));
- info.map_base =3D info.exe_base + 0x01000000;
-#else
- // If this system doesn't have PIE (position-independent executables)=
,
- // we have to choose a hardwired location for stage2.
- info.exe_base =3D VG_PGROUNDUP(&_end);
- info.map_base =3D KICKSTART_BASE + 0x01000000;
-#endif
-
- info.argv =3D NULL;
-
- snprintf(buf, sizeof(buf), "%s/%s", valgrind_lib, stage2);
-
- err =3D VG_(do_exec)(buf, &info);
-
- if (err !=3D 0) {
- fprintf(stderr, "valgrind: failed to load %s: %s\n",
- buf, strerror(err));
- exit(1);
- }
-
- /* Make sure stage2's dynamic linker can't tromp on the lower part
- of the address space. */
- padfile =3D as_openpadfile();
- as_pad(0, (void *)info.map_base, padfile);
- =20
- esp =3D fix_auxv(init_sp, &info, padfile);
-
- if (0) {
- printf("---------- launch stage 2 ----------\n");
- printf("eip=3D%p esp=3D%p\n", (void *)info.init_eip, esp);
- VG_(foreach_map)(prmap, /*dummy*/NULL);
- }
-
- VG_(debugLog)(1, "stage1", "main2(): starting stage2\n");
- VG_(jump_and_switch_stacks)(
- (Addr) esp, /* stack */
- (Addr) info.init_eip /* where to */
- );
-
- /*NOTREACHED*/
- assert(0);=20
-}
-
-
-int main(int argc, char** argv)
-{
- struct rlimit rlim;
- const char *cp;
- int i, loglevel;
-
- /* Start the debugging-log system ASAP. First find out how many=20
- "-d"s were specified. This is a pre-scan of the command line. */
- loglevel =3D 0;
- for (i =3D 1; i < argc; i++) {
- if (argv[i][0] !=3D '-')
- break;
- if (0 =3D=3D strcmp(argv[i], "--"))=20
- break;
- if (0 =3D=3D strcmp(argv[i], "-d"))=20
- loglevel++;
- }
-
- /* ... and start the debug logger. Now we can safely emit logging
- messages all through startup. */
- VG_(debugLog_startup)(loglevel, "Stage 1");
-
- // Initial stack pointer is to argc, which is immediately before argv=
[0]
- // on the stack. Nb: Assumes argc is word-aligned.
- init_sp =3D argv - 1;
-
- /* The Linux libc startup sequence leaves this in an apparently
- undefined state, but it really is defined, so mark it so. */
- VALGRIND_MAKE_READABLE(init_sp, sizeof(Word));
-
- cp =3D getenv(VALGRINDLIB);
-
- if (cp !=3D NULL)
- valgrind_lib =3D cp;
-
- /* Set the address space limit as high as it will go, since we make
- a lot of very large mappings. */
- getrlimit(RLIMIT_AS, &rlim);
- rlim.rlim_cur =3D rlim.rlim_max;
- setrlimit(RLIMIT_AS, &rlim);
-
- /* move onto another stack so we can play with the main one */
- VG_(debugLog)(1, "stage1", "main(): running main2() on new stack\n");
- VG_(jump_and_switch_stacks)(
- (Addr) stack + sizeof(stack), /* stack */
- (Addr) main2 /* where to */
- );
-
- /*NOTREACHED*/
- assert(0);=20
-}
-
-/*--------------------------------------------------------------------*/
-/*--- end stage1.c ---*/
-/*--------------------------------------------------------------------*/
|