From: Julian Seward Date: Sun, 23 Feb 2003 01:25:51 +0000 (+0000) Subject: Initial rough hack to spot the stack segment at startup by looking X-Git-Tag: svn/VALGRIND_1_9_4~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=424913d48bc554f7f1982143522798c6bc213768;p=thirdparty%2Fvalgrind.git Initial rough hack to spot the stack segment at startup by looking for a rwx mapping which contains the startup %esp. This should be more robust than the previous mechanism, which checked a small number of known places and gave up if none matched. This change is motivated by Gentoo Linux's high security mode, in which the stack location is chosen randomly for each new process. Thanks to Catherine Allen for helping out on this. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1422 --- diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index a7d9ad9651..0cb7b63567 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -616,6 +616,28 @@ static void usage ( void ) VG_(exit)(1); } + +/* Callback for lookiing for the stackl segment. */ +static Addr vg_foundstack_start = (Addr)NULL; +static UInt vg_foundstack_size = 0; + +static void vg_findstack_callback ( Addr start, UInt size, + Char r, Char w, Char x, + UInt foffset, UChar* filename ) +{ + Addr lastword; + if (size == 0) return; + if (r != 'r' || w != 'w' || x != 'x') return; + lastword = start + size - 4; + if (start <= VG_(esp_at_startup) && VG_(esp_at_startup) <= lastword) { + vg_foundstack_start = start; + vg_foundstack_size = size; + vg_assert(vg_foundstack_size > 0); + } +} + + + static void process_cmd_line_options ( void ) { Char* argv[M_VG_CMDLINE_OPTS]; @@ -646,7 +668,7 @@ static void process_cmd_line_options ( void ) change less often than the libc ones. */ { UInt* sp = 0; /* bogus init to keep gcc -O happy */ - +#if 0 /* locate the top of the stack */ if (VG_STACK_MATCHES_BASE( VG_(esp_at_startup), VG_STARTUP_STACK_BASE_1 )) { @@ -669,9 +691,33 @@ static void process_cmd_line_options ( void ) "constants defined in vg_include.h. You should investigate." ); } - + #endif /* we locate: NEW_AUX_ENT(1, AT_PAGESZ, ELF_EXEC_PAGESIZE) in the elf interpreter table */ + + + /* Look for the stack by reading /proc/self/maps and looking + for a section bracketing VG_(esp_at_startup) which has rwx + permissions. */ + + /* Appalling hack for Gentoo; round up to the next page. */ + sp = (UInt*)VG_(esp_at_startup); + + VG_(read_procselfmaps)( vg_findstack_callback ); + /* make vg_foundstack_start and +static UInt vg_foundstack_size = 0; +be the stack. */ + if (vg_foundstack_size == 0) + args_grok_error("Cannot determine stack segment " + "from /proc/self/maps"); + + if (0) + VG_(printf)("stack segment is %p .. %p\n", vg_foundstack_start, vg_foundstack_start + vg_foundstack_size - 4 ); + + sp = (UInt*)(vg_foundstack_start+ vg_foundstack_size); + vg_assert((((UInt)(sp)) % VKI_BYTES_PER_PAGE) == 0); + + sp -= 2; while (sp[0] != VKI_AT_PAGESZ || sp[1] != 4096) { /* VG_(printf)("trying %p\n", sp); */ @@ -1308,6 +1354,15 @@ void VG_(main) ( void ) VG_(stack)[10000-1-i] = (UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321; } + /* Hook to delay things long enough so we can get the pid and + attach GDB in another shell. */ + if (0) { + Int p, q; + VG_(printf)("pid=%d\n", VG_(getpid)()); + for (p = 0; p < 50000; p++) + for (q = 0; q < 50000; q++) ; + } + /* Setup stuff that depends on the skin. Must be before: - vg_init_baseBlock(): to register helpers - process_cmd_line_options(): to register skin name and description, @@ -1327,15 +1382,6 @@ void VG_(main) ( void ) Comes after SK_(post_clo_init) in case it registers helpers. */ vg_init_baseBlock(); - /* Hook to delay things long enough so we can get the pid and - attach GDB in another shell. */ - if (0) { - Int p, q; - VG_(printf)("pid=%d\n", VG_(getpid)()); - for (p = 0; p < 5000; p++) - for (q = 0; q < 50000; q++) ; - } - /* Initialise the scheduler, and copy the client's state from baseBlock into VG_(threads)[1]. This has to come before signal initialisations. */ diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 63efbb6471..b1f73a21d0 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -626,6 +626,7 @@ void VG_(scheduler_init) ( void ) startup_esp = VG_(baseBlock)[VGOFF_(m_esp)]; +#if 0 if (VG_STACK_MATCHES_BASE(startup_esp, VG_STARTUP_STACK_BASE_1) || VG_STACK_MATCHES_BASE(startup_esp, VG_STARTUP_STACK_BASE_2) || VG_STACK_MATCHES_BASE(startup_esp, VG_STARTUP_STACK_BASE_3) @@ -642,6 +643,7 @@ void VG_(scheduler_init) ( void ) ); VG_(core_panic)("unexpected %esp at startup"); } +#endif for (i = 0 /* NB; not 1 */; i < VG_N_THREADS; i++) { mostly_clear_thread_record(i);