]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Initial rough hack to spot the stack segment at startup by looking
authorJulian Seward <jseward@acm.org>
Sun, 23 Feb 2003 01:25:51 +0000 (01:25 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 23 Feb 2003 01:25:51 +0000 (01:25 +0000)
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

coregrind/vg_main.c
coregrind/vg_scheduler.c

index a7d9ad965169ba361da0954da8c5407f6f9c57d2..0cb7b6356748a6a666a1df9b8790409884a34c2c 100644 (file)
@@ -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. */
index 63efbb6471eef65196c601e6056c598436f3d5f0..b1f73a21d052531ba4591a478b01628ed01cbf31 100644 (file)
@@ -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);