From: Nicholas Nethercote Date: Mon, 18 Oct 2004 11:52:17 +0000 (+0000) Subject: Arch-abstraction: a nice change that removes the need for ume_entry.S. Instead X-Git-Tag: svn/VALGRIND_3_0_0~1512 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=493933b1c6c0acaaabe46e99e4e27b608aef02ab;p=thirdparty%2Fvalgrind.git Arch-abstraction: a nice change that removes the need for ume_entry.S. Instead of using an assembly hack to find the stack pointer at startup, we find it from argv. It's much simpler, avoids linking games, is platform independent, and works on PPC. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2782 --- diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am index b08cc3f6ab..56c006f958 100644 --- a/coregrind/Makefile.am +++ b/coregrind/Makefile.am @@ -30,12 +30,11 @@ CLEANFILES = vg_toolint.c vg_toolint.h vg_replace_malloc.c vg_intercept.c valgrind_SOURCES = \ ume.c \ - ${VG_ARCH}/ume_entry.S \ \ stage1.c \ ${VG_ARCH}/jmp_with_stack.c valgrind_DEPENDENCIES = -valgrind_LDFLAGS=-static -g -Wl,-e,_ume_entry +valgrind_LDFLAGS=-static -g valgrind_LDADD= # Where stage2 will be put. @@ -46,7 +45,6 @@ KICKSTART_BASE=0xb0000000 stage2_SOURCES = \ ume.c \ - ${VG_ARCH}/ume_entry.S \ \ vg_scheduler.c \ vg_default.c \ @@ -81,7 +79,7 @@ stage2_SOURCES = \ vg_transtab.c \ vg_cpuid.S stage2_DEPENDENCIES = $(srcdir)/valgrind.vs ${VG_ARCH}/stage2.lds -stage2_LDFLAGS=-Wl,--export-dynamic -Wl,-e,_ume_entry -g \ +stage2_LDFLAGS=-Wl,--export-dynamic -g \ -Wl,-defsym,kickstart_base=$(KICKSTART_BASE) \ -Wl,-T,${VG_ARCH}/stage2.lds \ -Wl,-version-script $(srcdir)/valgrind.vs diff --git a/coregrind/stage1.c b/coregrind/stage1.c index 5b4e4dbf91..c6ae5bc492 100644 --- a/coregrind/stage1.c +++ b/coregrind/stage1.c @@ -46,6 +46,9 @@ 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 = VG_LIBDIR; @@ -257,7 +260,7 @@ static void main2(void) char buf[strlen(valgrind_lib) + sizeof(stage2) + 16]; info.exe_base = PGROUNDUP(&_end); - info.exe_end = PGROUNDDN(ume_exec_esp); + info.exe_end = PGROUNDDN(init_sp); /* XXX FIXME: how can stage1 know where stage2 wants things placed? Options: @@ -283,7 +286,7 @@ static void main2(void) padfile = as_openpadfile(); as_pad(0, (void *)info.map_base, padfile); - esp = fix_auxv(ume_exec_esp, &info, padfile); + esp = fix_auxv(init_sp, &info, padfile); if (0) { printf("---------- launch stage 2 ----------\n"); @@ -294,7 +297,7 @@ static void main2(void) jmp_with_stack(info.init_eip, (addr_t)esp); } -int main(void) +int main(int argc, char** argv) { struct rlimit rlim; const char *cp = getenv(VALGRINDLIB); @@ -302,7 +305,9 @@ int main(void) if (cp != NULL) valgrind_lib = cp; - assert(ume_exec_esp != NULL); + // Initial stack pointer is to argc, which is immediately before argv[0] + // on the stack. + init_sp = argv - 1; /* Set the address space limit as high as it will go, since we make a lot of very large mappings. */ diff --git a/coregrind/ume.h b/coregrind/ume.h index 474a0a0fce..a015ff07d8 100644 --- a/coregrind/ume.h +++ b/coregrind/ume.h @@ -55,8 +55,6 @@ void foreach_map(int (*fn)(char *start, char *end, /* Integer type the same size as a pointer */ typedef ESZ(Addr) addr_t; -extern void *ume_exec_esp; /* esp on entry at exec time */ - // Jump to a new 'ip' with the stack 'sp'. void jmp_with_stack(addr_t ip, addr_t sp) __attribute__((noreturn)); diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index 23c437a164..cf61287d68 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -362,9 +362,9 @@ static void newpid(ThreadId unused) /*====================================================================*/ /* Look for our AUXV table */ -int scan_auxv(void) +int scan_auxv(void* init_sp) { - const struct ume_auxv *auxv = find_auxv((int *)ume_exec_esp); + const struct ume_auxv *auxv = find_auxv((int *)init_sp); int padfile = -1, found = 0; for (; auxv->a_type != AT_NULL; auxv++) @@ -908,7 +908,8 @@ static char *copy_str(char **tab, const char *str) | undefined | : : */ -static Addr setup_client_stack(char **orig_argv, char **orig_envp, +static Addr setup_client_stack(void* init_sp, + char **orig_argv, char **orig_envp, const struct exeinfo *info, UInt** client_auxv) { @@ -928,7 +929,7 @@ static Addr setup_client_stack(char **orig_argv, char **orig_envp, addr_t cl_esp; /* client stack base (initial esp) */ /* use our own auxv as a prototype */ - orig_auxv = find_auxv(ume_exec_esp); + orig_auxv = find_auxv(init_sp); /* ==================== compute sizes ==================== */ @@ -2576,7 +2577,10 @@ int main(int argc, char **argv) // Check we were launched by stage1 // p: n/a //-------------------------------------------------------------- - padfile = scan_auxv(); + { + void* init_sp = argv - 1; + padfile = scan_auxv(init_sp); + } if (0) { printf("========== main() ==========\n"); @@ -2650,7 +2654,11 @@ int main(int argc, char **argv) // p: load_client() [for 'info'] // p: fix_environment() [for 'env'] //-------------------------------------------------------------- - esp_at_startup = setup_client_stack(cl_argv, env, &info, &client_auxv); + { + void* init_sp = argv - 1; + esp_at_startup = setup_client_stack(init_sp, cl_argv, env, &info, + &client_auxv); + } if (0) printf("entry=%p client esp=%p vg_argc=%d brkbase=%p\n", diff --git a/coregrind/x86/Makefile.am b/coregrind/x86/Makefile.am index d104a04687..17801a3984 100644 --- a/coregrind/x86/Makefile.am +++ b/coregrind/x86/Makefile.am @@ -11,8 +11,7 @@ noinst_HEADERS = \ noinst_LIBRARIES = libarch.a EXTRA_DIST = \ - jmp_with_stack.c \ - ume_entry.S + jmp_with_stack.c BUILT_SOURCES = stage2.lds CLEANFILES = stage2.lds diff --git a/coregrind/x86/ume_entry.S b/coregrind/x86/ume_entry.S deleted file mode 100644 index 0802baf915..0000000000 --- a/coregrind/x86/ume_entry.S +++ /dev/null @@ -1,41 +0,0 @@ - -/* - This file is part of Valgrind, an extensible x86 protected-mode - emulator for monitoring program execution on x86-Unixes. - - Copyright (C) 2000-2004 Julian Seward - jseward@acm.org - - 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. -*/ - - .text - .globl _ume_entry - - /* Record the very initial value of %esp before starting the - rest of the executable */ -_ume_entry: - movl %esp, ume_exec_esp - jmp _start - - .data - .globl ume_exec_esp -ume_exec_esp: .long 0 - -/* Let the linker know we don't need an executable stack */ -.section .note.GNU-stack,"",@progbits diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am index 18809253c6..f3e7f947aa 100644 --- a/memcheck/tests/Makefile.am +++ b/memcheck/tests/Makefile.am @@ -165,9 +165,7 @@ hello_SOURCES = hello.c hello_LDFLAGS = -Wl,-defsym,kickstart_base=0x50000000 \ -Wl,-T,../../coregrind/${VG_ARCH}/stage2.lds vgtest_ume_SOURCES = vgtest_ume.c -vgtest_ume_LDFLAGS = -Wl,-e,_ume_entry vgtest_ume_LDADD = ../../coregrind/ume.o \ - ../../coregrind/ume_entry.o \ ../../coregrind/jmp_with_stack.o # must be built with these flags -- bug only occurred with them diff --git a/memcheck/tests/vgtest_ume.c b/memcheck/tests/vgtest_ume.c index 458f6f0b9f..84ca3910e1 100644 --- a/memcheck/tests/vgtest_ume.c +++ b/memcheck/tests/vgtest_ume.c @@ -1,6 +1,6 @@ #define ELFSZ 32 -// This file is a unit self-test for ume.c, ume_entry.c, jmp_with_stack.c +// This file is a unit self-test for ume.c, jmp_with_stack.c #include #include @@ -10,26 +10,28 @@ #define STKSZ (64*1024) +static void* init_sp; + //------------------------------------------------------------------- // Test foreach_map() //------------------------------------------------------------------- -static int x; +static int x[8]; static int f(char *start, char *end, const char *perm, off_t off, int maj, int min, int ino, void* dummy) { // Just do some nonsense action with each of the values so that Memcheck // checks that they are valid. - x = ( start == 0 ? 0 : 1 ); - x = ( end == 0 ? 0 : 1 ); - x = ( perm == 0 ? 0 : 1 ); - x = ( off == 0 ? 0 : 1 ); - x = ( maj == 0 ? 0 : 1 ); - x = ( min == 0 ? 0 : 1 ); - x = ( ino == 0 ? 0 : 1 ); - x = ( dummy == 0 ? 0 : 1 ); - - return /*True*/1; + x[0] = ( start == 0 ? 0 : 1 ); + x[1] = ( end == 0 ? 0 : 1 ); + x[2] = ( perm == 0 ? 0 : 1 ); + x[3] = ( off == 0 ? 0 : 1 ); + x[4] = ( maj == 0 ? 0 : 1 ); + x[5] = ( min == 0 ? 0 : 1 ); + x[6] = ( ino == 0 ? 0 : 1 ); + x[7] = ( dummy == 0 ? 0 : 1 ); + + return /*True*/1 + x[0] + x[1] + x[2] + x[3] + x[4] + x[5] + x[6] + x[7]; } static void test__foreach_map(void) @@ -46,14 +48,14 @@ static void test__find_auxv(void) { struct ume_auxv *auxv; - assert(ume_exec_esp != NULL); + assert(init_sp != NULL); fprintf(stderr, "Calling find_auxv()\n"); - auxv = find_auxv((int*)ume_exec_esp); + auxv = find_auxv((int*)init_sp); // Check the auxv value looks sane - assert((void*)auxv > (void*)ume_exec_esp); - assert((unsigned int)auxv - (unsigned int)ume_exec_esp < 0x10000); + assert((void*)auxv > (void*)init_sp); + assert((unsigned int)auxv - (unsigned int)init_sp < 0x10000); // Scan the auxv, check it looks sane for (; auxv->a_type != AT_NULL; auxv++) { @@ -136,8 +138,10 @@ static void test__do_exec(void) assert(0); // UNREACHABLE } -int main(void) +int main(int argc, char** argv) { + init_sp = argv - 1; + test__foreach_map(); test__find_auxv(); test__do_exec();