]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Removed all uses of nested functions as they only work with gcc and
authorTom Hughes <tom@compton.nu>
Sun, 27 Jun 2004 17:37:21 +0000 (17:37 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 27 Jun 2004 17:37:21 +0000 (17:37 +0000)
cause the stack to be marked as executable in order for them to work.

All assembler files have also had a declaration added so that the
object they generate will be marked as not needing an executable stack.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2446

21 files changed:
coregrind/stage1.c
coregrind/ume.c
coregrind/vg_cpuid.S
coregrind/vg_dispatch.S
coregrind/vg_hashtable.c
coregrind/vg_helpers.S
coregrind/vg_main.c
coregrind/vg_mylibc.c
coregrind/vg_scheduler.c
coregrind/vg_symtypes.c
coregrind/vg_syscall.S
coregrind/vg_transtab.c
coregrind/x86/ume_entry.S
helgrind/hg_main.c
include/vg_skin.h.base
massif/ms_main.c
memcheck/mac_malloc_wrappers.c
memcheck/mac_needs.c
memcheck/mac_shared.h
memcheck/mc_clientreqs.c
memcheck/mc_helpers.S

index 8b1213037976ea595317080d4735b463af98ad87..3dffe731ce2e3b2c4f9ba7b5f3d1be105e758f04 100644 (file)
@@ -156,6 +156,12 @@ static void *fix_auxv(void *v_init_esp, const struct exeinfo *info)
    return v_init_esp;
 }
 
+static int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
+   printf("mapping %10p-%10p %s %02x:%02x %d\n",
+          start, end, perm, maj, min, ino);
+   return 1;
+}
+
 static void hoops(void)
 {
    int err;
@@ -193,11 +199,6 @@ static void hoops(void)
    esp = fix_auxv(ume_exec_esp, &info);
 
    if (0) {
-      int prmap(void *start, void *end, const char *perm, off_t off, int maj, int min, int ino) {
-        printf("mapping %10p-%10p %s %02x:%02x %d\n",
-               start, end, perm, maj, min, ino);
-        return 1;
-      }
       printf("---------- launch stage 2 ----------\n");
       printf("eip=%p esp=%p\n", (void *)info.init_eip, esp);
       foreach_map(prmap);
index ff76d0c35f28bb2f7c22e422040dbf30cf8d0c50..8ae974d36f43f12ed26db4b4591b5b088415c58f 100644 (file)
@@ -144,25 +144,27 @@ void foreach_map(int (*fn)(void *start, void *end,
    }
 }
 
+static char *fillgap_addr;
+static char *fillgap_end;
+
+static int fillgap(void *segstart, void *segend, const char *perm, off_t off, 
+                   int maj, int min, int ino) {
+   if ((char *)segstart >= fillgap_end)
+      return 0;
+
+   if ((char *)segstart > fillgap_addr)
+      mmap(fillgap_addr, (char *)segstart-fillgap_addr, PROT_NONE,
+           MAP_FIXED|MAP_PRIVATE, padfile, 0);
+   fillgap_addr = segend;
+   
+   return 1;
+}
+
 /* pad all the empty spaces in a range of address space to stop
    interlopers */
 void as_pad(void *start, void *end)
 {
    char buf[1024];
-   char *addr;
-
-   int fillgap(void *segstart, void *segend, const char *perm, off_t off, 
-              int maj, int min, int ino) {
-      if (segstart >= end)
-        return 0;
-
-      if ((char *)segstart > addr)
-        mmap(addr, (char *)segstart-addr, PROT_NONE, MAP_FIXED|MAP_PRIVATE,
-             padfile, 0);
-      addr = segend;
-        
-      return 1;
-   }
 
    if (padfile == -1) {
       int seq = 1;
@@ -176,47 +178,54 @@ void as_pad(void *start, void *end)
       fstat(padfile, &padstat);
    }
 
-   addr = start;
+   fillgap_addr = start;
+   fillgap_end = end;
 
    foreach_map(fillgap);
        
-   if (addr < (char *)end)
-      mmap(addr, (char *)end-addr, PROT_NONE, MAP_FIXED|MAP_PRIVATE,
-          padfile, 0);
+   if (fillgap_addr < fillgap_end)
+      mmap(fillgap_addr, fillgap_end-fillgap_addr, PROT_NONE,
+           MAP_FIXED|MAP_PRIVATE, padfile, 0);
 }
 
-/* remove padding from a range of address space - padding is always a
-   mapping of padfile*/
-void as_unpad(void *start, void *end)
-{
-   int killpad(void *segstart, void *segend, const char *perm, off_t off, 
-              int maj, int min, int ino) {
-      void *b, *e;
-
-      if (padstat.st_dev != makedev(maj, min) || padstat.st_ino != ino)
-        return 1;
-
-      if (segend <= start || segstart >= end)
-        return 1;
+static void *killpad_start;
+static void *killpad_end;
 
-      if (segstart <= start)
-        b = start;
-      else
-        b = segstart;
-
-      if (segend >= end)
-        e = end;
-      else
-        e = segend;
-
-      munmap(b, (char *)e-(char *)b);
+static int killpad(void *segstart, void *segend, const char *perm, off_t off, 
+                   int maj, int min, int ino) {
+   void *b, *e;
 
+   if (padstat.st_dev != makedev(maj, min) || padstat.st_ino != ino)
       return 1;
-   }
+   
+   if (segend <= killpad_start || segstart >= killpad_end)
+      return 1;
+   
+   if (segstart <= killpad_start)
+      b = killpad_start;
+   else
+      b = segstart;
+   
+   if (segend >= killpad_end)
+      e = killpad_end;
+   else
+      e = segend;
+   
+   munmap(b, (char *)e-(char *)b);
+   
+   return 1;
+}
 
+/* remove padding from a range of address space - padding is always a
+   mapping of padfile*/
+void as_unpad(void *start, void *end)
+{
    if (padfile == -1)  /* no padfile, no padding */
       return;
-
+   
+   killpad_start = start;
+   killpad_end = end;
+   
    foreach_map(killpad);
 }
 
index a5386f9a03264537953ee169030db32860a9180f..85c63bc323a50a5ebd6a211f9dfd85b40da08a66 100644 (file)
@@ -75,3 +75,10 @@ VG_(cpuid):
         movl    %ebp, %esp
         popl    %ebp
         ret
+        
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+##--------------------------------------------------------------------##
+##--- end                                              vg_cpuid.S ---##
+##--------------------------------------------------------------------##
index 997bf17f3dc9be745087dc5cb90aa27993036b4d..546f5ef0a93e778f42dce7780d0a6280895789a1 100644 (file)
@@ -222,7 +222,9 @@ panic_msg_ebp:
 .ascii "vg_dispatch: %ebp has invalid value!"
 .byte  0
 .text  
-
+        
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
 
 ##--------------------------------------------------------------------##
 ##--- end                                            vg_dispatch.S ---##
index 11a6d7c8dd60acc69684cfc0ec0ffb398a92ba11..f1966cd3066994a0b2ecaed6273ecd8352ccdea8 100644 (file)
@@ -133,27 +133,31 @@ VgHashNode** VG_(HT_to_array) ( VgHashTable table, /*OUT*/ UInt* n_shadows )
 }
 
 /* Return the first VgHashNode satisfying the predicate p. */
-VgHashNode* VG_(HT_first_match) ( VgHashTable table, Bool (*p) ( VgHashNode* ))
+VgHashNode* VG_(HT_first_match) ( VgHashTable table,
+                                  Bool (*p) ( VgHashNode*, void* ),
+                                  void* d )
 {
    UInt      i;
    VgHashNode* node;
 
    for (i = 0; i < VG_N_CHAINS; i++)
       for (node = table[i]; node != NULL; node = node->next)
-         if ( p(node) )
+         if ( p(node, d) )
             return node;
 
    return NULL;
 }
 
-void VG_(HT_apply_to_all_nodes)( VgHashTable table, void (*f)(VgHashNode*) )
+void VG_(HT_apply_to_all_nodes)( VgHashTable table,
+                                 void (*f)(VgHashNode*, void*),
+                                 void* d )
 {
    UInt      i;
    VgHashNode* node;
 
    for (i = 0; i < VG_N_CHAINS; i++) {
       for (node = table[i]; node != NULL; node = node->next) {
-         f(node);
+         f(node, d);
       }
    }
 }
index 08bbfc95b4ada1f46ef1c6d73432f62877830ffe..5d801c3295d0754165acbbb13e6755e5780e5ee0 100644 (file)
@@ -723,7 +723,10 @@ VG_(helper_cmpxchg8b):
 VG_(helper_undefined_instruction):
 1:     ud2
        jmp     1b
-                       
+               
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+               
 ##--------------------------------------------------------------------##
 ##--- end                                             vg_helpers.S ---##
 ##--------------------------------------------------------------------##
index 4b187f055423e0a67169185e4164939e09c0c6fe..70873438df8fecec2bf609f6d3bda4cc18f42035 100644 (file)
@@ -764,17 +764,20 @@ static void get_command_line( int argc, char** argv,
 
 /* Scan a colon-separated list, and call a function on each element.
    The string must be mutable, because we insert a temporary '\0', but
-   the string will end up unmodified.  (*func) should return 1 if it
+   the string will end up unmodified.  (*func) should return True if it
    doesn't need to see any more.
+
+   This routine will return True if (*func) returns True and False if
+   it reaches the end of the list without that happening.
 */
-static void scan_colsep(char *colsep, int (*func)(const char *))
+static Bool scan_colsep(char *colsep, Bool (*func)(const char *))
 {
    char *cp, *entry;
    int end;
 
    if (colsep == NULL ||
        *colsep == '\0')
-      return;
+      return False;
 
    entry = cp = colsep;
 
@@ -786,12 +789,21 @@ static void scan_colsep(char *colsep, int (*func)(const char *))
 
         *cp = '\0';
         if ((*func)(entry))
-           end = 1;
+           return True;
         *cp = save;
         entry = cp+1;
       }
       cp++;
    } while(!end);
+
+   return False;
+}
+
+static Bool contains(const char *p) {
+   if (VG_STREQ(p, VG_(libdir))) {
+      return True;
+   }
+   return False;
 }
 
 /* Prepare the client's environment.  This is basically a copy of our
@@ -855,22 +867,11 @@ static char **fix_environment(char **origenv, const char *preload)
    /* Walk over the new environment, mashing as we go */
    for (cpp = ret; cpp && *cpp; cpp++) {
       if (memcmp(*cpp, ld_library_path, ld_library_path_len) == 0) {
-        int done = 0;
-        int contains(const char *p) {
-           if (VG_STREQ(p, VG_(libdir))) {
-              done = 1;
-              return 1;
-           }
-           return 0;
-        }
-
         /* If the LD_LIBRARY_PATH already contains libdir, then don't
            bother adding it again, even if it isn't the first (it
            seems that the Java runtime will keep reexecing itself
            unless its paths are at the front of LD_LIBRARY_PATH) */
-        scan_colsep(*cpp + ld_library_path_len, contains);
-
-        if (!done) {
+         if (!scan_colsep(*cpp + ld_library_path_len, contains)) {
            int len = strlen(*cpp) + vgliblen*2 + 16;
            char *cp = malloc(len);
 
@@ -1202,33 +1203,35 @@ static Addr setup_client_stack(char **orig_argv, char **orig_envp,
 /*=== Find executable                                              ===*/
 /*====================================================================*/
 
+static const char* executable_name;
+
+static Bool match_executable(const char *entry) {
+   char buf[strlen(entry) + strlen(executable_name) + 2];
+
+   /* empty PATH element means . */
+   if (*entry == '\0')
+      entry = ".";
+
+   snprintf(buf, sizeof(buf), "%s/%s", entry, executable_name);
+   
+   if (access(buf, R_OK|X_OK) == 0) {
+      executable_name = strdup(buf);
+      vg_assert(NULL != executable_name);
+      return True;
+   }
+   return False;
+}
+
 static const char* find_executable(const char* exec)
 {
    vg_assert(NULL != exec);
-   if (strchr(exec, '/') == NULL) {
+   executable_name = exec;
+   if (strchr(executable_name, '/') == NULL) {
       /* no '/' - we need to search the path */
       char *path = getenv("PATH");
-      int pathlen = path ? strlen(path) : 0;
-
-      int match_exe(const char *entry) {
-         char buf[pathlen + strlen(entry) + 3];
-
-         /* empty PATH element means . */
-         if (*entry == '\0')
-            entry = ".";
-
-         snprintf(buf, sizeof(buf), "%s/%s", entry, exec);
-
-         if (access(buf, R_OK|X_OK) == 0) {
-            exec = strdup(buf);
-            vg_assert(NULL != exec);
-            return 1;
-         }
-         return 0;
-      }
-      scan_colsep(path, match_exe);
+      scan_colsep(path, match_executable);
    }
-   return exec;
+   return executable_name;
 }
 
 
@@ -2627,6 +2630,13 @@ void VG_(do_sanity_checks) ( Bool force_expensive )
 /*=== main()                                                       ===*/
 /*====================================================================*/
 
+static int prmap(void *start, void *end, const char *perm, off_t off, 
+                 int maj, int min, int ino) {
+   printf("mapping %10p-%10p %s %02x:%02x %d\n",
+          start, end, perm, maj, min, ino);
+   return True;
+}
+
 int main(int argc, char **argv)
 {
    char **cl_argv;
@@ -2675,12 +2685,6 @@ int main(int argc, char **argv)
    scan_auxv();
 
    if (0) {
-      int prmap(void *start, void *end, const char *perm, off_t off, 
-                int maj, int min, int ino) {
-         printf("mapping %10p-%10p %s %02x:%02x %d\n",
-                start, end, perm, maj, min, ino);
-         return True;
-      }
       printf("========== main() ==========\n");
       foreach_map(prmap);
    }
index 7b11f6eec39d2b4d3e387b9d415509c04fa3a48f..255316b68ee9cdcc384f8b462f8c3a3e080ab2d2 100644 (file)
@@ -730,18 +730,22 @@ UInt VG_(printf) ( const char *format, ... )
    return ret;
 }
 
-
 /* A general replacement for sprintf(). */
+
+static Char *vg_sprintf_ptr;
+
+static void add_to_vg_sprintf_buf ( Char c )
+{
+   *vg_sprintf_ptr++ = c;
+}
+
 UInt VG_(sprintf) ( Char* buf, Char *format, ... )
 {
    Int ret;
    va_list vargs;
-   Char *ptr = buf;
-   static void add_to_vg_sprintf_buf ( Char c )
-   {
-      *ptr++ = c;
-   }
-   
+
+   vg_sprintf_ptr = buf;
+
    va_start(vargs,format);
 
    ret = VG_(vprintf) ( add_to_vg_sprintf_buf, format, vargs );
index 3d33bad926237c7edc219373842ee6a805b19f76..dd6f1658d6850c99fef530108aa24696fcd5832d 100644 (file)
@@ -165,7 +165,8 @@ Bool VG_(is_valid_or_empty_tid) ( ThreadId tid )
    VG_(baseBlock)-resident thread. 
 */
 ThreadId VG_(first_matching_thread_stack)
-              ( Bool (*p) ( Addr stack_min, Addr stack_max ))
+              ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ),
+                void* d )
 {
    ThreadId tid, tid_to_skip;
 
@@ -176,7 +177,7 @@ ThreadId VG_(first_matching_thread_stack)
    if (vg_tid_currently_in_baseBlock != VG_INVALID_THREADID) {
       tid = vg_tid_currently_in_baseBlock;
       if ( p ( VG_(baseBlock)[VGOFF_(m_esp)], 
-               VG_(threads)[tid].stack_highest_word) )
+               VG_(threads)[tid].stack_highest_word, d ) )
          return tid;
       else
          tid_to_skip = tid;
@@ -186,7 +187,7 @@ ThreadId VG_(first_matching_thread_stack)
       if (VG_(threads)[tid].status == VgTs_Empty) continue;
       if (tid == tid_to_skip) continue;
       if ( p ( VG_(threads)[tid].m_esp,
-               VG_(threads)[tid].stack_highest_word) )
+               VG_(threads)[tid].stack_highest_word, d ) )
          return tid;
    }
    return VG_INVALID_THREADID;
index f291d16717f5e2926aa6cc85ab8a62fd6089b8fb..f8d4b896d1bb88b146514e9cc371f6d849eecdb9 100644 (file)
@@ -661,6 +661,33 @@ static inline Bool is_followable(SymType *ty)
    return ty->kind == TyPointer || is_composite(ty);
 }
 
+/* Result buffer */
+static Char *describe_addr_buf;
+static UInt describe_addr_bufidx;
+static UInt describe_addr_bufsz;
+
+/* Add a character to the result buffer */
+static void describe_addr_addbuf(Char c) {
+   if ((describe_addr_bufidx+1) >= describe_addr_bufsz) {
+      Char *n;
+    
+      if (describe_addr_bufsz == 0)
+         describe_addr_bufsz = 8;
+      else
+         describe_addr_bufsz *= 2;
+    
+      /* use tool malloc so that the skin client can free it */
+      n = VG_(malloc)(describe_addr_bufsz);
+      if (describe_addr_buf != NULL && describe_addr_bufidx != 0)
+         VG_(memcpy)(n, describe_addr_buf, describe_addr_bufidx);
+      if (describe_addr_buf != NULL)
+         VG_(free)(describe_addr_buf);
+      describe_addr_buf = n;
+   }
+   describe_addr_buf[describe_addr_bufidx++] = c;
+   describe_addr_buf[describe_addr_bufidx] = '\0';
+}
+
 #define MAX_PLY                7       /* max depth we go */
 #define MAX_ELEMENTS   5000    /* max number of array elements we scan */
 #define MAX_VARS       10000   /* max number of variables total traversed */
@@ -673,34 +700,12 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
    Variable *list;             /* worklist */
    Variable *keeplist;         /* container variables */
    Variable *found;            /* the chain we found */
-   Char *buf = NULL;           /* the result */
-   UInt bufsz = 0;
-   UInt bufidx = 0;
    Int created=0, freed=0;
    Int numvars = MAX_VARS;
 
-   /* add a character to the result buffer */
-   void addbuf(Char c) {
-      if ((bufidx+1) >= bufsz) {
-        Char *n;
-
-        if (bufsz == 0)
-           bufsz = 8;
-        else
-           bufsz *= 2;
-
-        /* use tool malloc so that the skin client can free it */
-        n = VG_(malloc)(bufsz);
-        if (buf != NULL && bufidx != 0)
-           VG_(memcpy)(n, buf, bufidx);
-        if (buf != NULL)
-           VG_(free)(buf);
-        buf = n;
-      }
-      buf[bufidx++] = c;
-      buf[bufidx] = '\0';
-   }
-
+   describe_addr_buf = NULL;
+   describe_addr_bufidx = 0;
+   describe_addr_bufsz = 0;
 
    clear_visited();
 
@@ -1013,7 +1018,7 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
               found->container->name = NULL;
               found->container = found->container->container;
            } else {
-              bprintf(addbuf, "&(");
+              bprintf(describe_addr_addbuf, "&(");
               ptr = False;
            }
 
@@ -1025,13 +1030,13 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
 
         *ep++ = '\0';
 
-        bprintf(addbuf, sp);
+        bprintf(describe_addr_addbuf, sp);
 
         if (addr != found->valuep)
-           bprintf(addbuf, "+%d", addr - found->valuep);
+           bprintf(describe_addr_addbuf, "+%d", addr - found->valuep);
 
         if (VG_(get_filename_linenum)(eip, file, sizeof(file), &line))
-           bprintf(addbuf, " at %s:%d", file, line, addr);
+           bprintf(describe_addr_addbuf, " at %s:%d", file, line, addr);
       }
    }
 
@@ -1043,9 +1048,9 @@ Char *VG_(describe_addr)(ThreadId tid, Addr addr)
    clear_visited();
 
    if (debug)
-      VG_(printf)("returning buf=%s\n", buf);
+      VG_(printf)("returning buf=%s\n", describe_addr_buf);
 
-   return buf;
+   return describe_addr_buf;
 }
 #endif /* TEST */
 
index d7efec06f2495d4057bddb766e6efe829ac40e7c..e46d1b46651bab75c94f0f289fc5873ddcc84663 100644 (file)
@@ -117,7 +117,10 @@ VG_(clone):
 VG_(sigreturn):
        movl    $__NR_rt_sigreturn, %eax
        int     $0x80
-       
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
 ##--------------------------------------------------------------------##
 ##--- end                                             vg_syscall.S ---##
 ##--------------------------------------------------------------------##
index 234ff92cff735484434ef25da50cf01c47280399..64770f548e5fc56e61ef5a8cf563b2fe35445eac 100644 (file)
@@ -165,19 +165,28 @@ void unchain_tce(TCEntry *tce)
 }
 
 /* Unchain any jumps pointing to a sector we're about to free */
+static Addr sector_base;
+static Addr sector_len;
+
+static
+void unchain_site_for_sector(Addr a) {
+   Addr jmp = VG_(get_jmp_dest)(a);
+   if (jmp >= sector_base && jmp < (sector_base+sector_len))
+      VG_(unchain_jumpsite)(a);
+}
+
+static
+void unchain_tce_for_sector(TCEntry *tce) {
+   for_each_jumpsite(tce, unchain_site_for_sector);
+}
+
 static
 void unchain_sector(Int s, Addr base, UInt len)
 {
-   void unchain_site(Addr a) {
-      Addr jmp = VG_(get_jmp_dest)(a);
-      if (jmp >= base && jmp < (base+len))
-        VG_(unchain_jumpsite)(a);
-   }
-   void _unchain_tce(TCEntry *tce) {
-      for_each_jumpsite(tce, unchain_site);
-   }
+   sector_base = base;
+   sector_len = len;
 
-   for_each_tc(s, _unchain_tce);
+   for_each_tc(s, unchain_tce_for_sector);
 }
 
 
index e38fc1849ce834cb72e918ecbd93b6d5840d6410..0802baf9157d6cfe8b0b99b5fbd79e1de092fee7 100644 (file)
@@ -36,3 +36,6 @@ _ume_entry:
        .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
index cedde2e83bf8f1b21d56a977f8b1409708ae00d6..a853e63f0ee7bb60c794d07780d56a6a49857c05 100644 (file)
@@ -1404,37 +1404,38 @@ static void find_mutex_range(Addr start, Addr end, Bool (*action)(Mutex *))
 #define MARK_LOOP      (graph_mark+0)
 #define MARK_DONE      (graph_mark+1)
 
-static Bool check_cycle(const Mutex *start, const LockSet* lockset)
+static Bool check_cycle_inner(const Mutex *mutex, const LockSet *ls)
 {
-   Bool check_cycle_inner(const Mutex *mutex, const LockSet *ls)
-   {
-      static const Bool debug = False;
-      Int i;
-
-      if (mutex->mark == MARK_LOOP)
-        return True;           /* found cycle */
-      if (mutex->mark == MARK_DONE)
-        return False;          /* been here before, its OK */
+   static const Bool debug = False;
+   Int i;
 
-      ((Mutex*)mutex)->mark = MARK_LOOP;
-        
+   if (mutex->mark == MARK_LOOP)
+      return True;             /* found cycle */
+   if (mutex->mark == MARK_DONE)
+      return False;            /* been here before, its OK */
+   
+   ((Mutex*)mutex)->mark = MARK_LOOP;
+   
+   if (debug)
+      VG_(printf)("mark=%d visiting %p%(y mutex->lockset=%d\n",
+                  graph_mark, mutex->mutexp, mutex->mutexp, mutex->lockdep);
+   for(i = 0; i < ls->setsize; i++) {
+      const Mutex *mx = ls->mutex[i];
+     
       if (debug)
-        VG_(printf)("mark=%d visiting %p%(y mutex->lockset=%d\n",
-                    graph_mark, mutex->mutexp, mutex->mutexp, mutex->lockdep);
-      for(i = 0; i < ls->setsize; i++) {
-        const Mutex *mx = ls->mutex[i];
-
-        if (debug)
-           VG_(printf)("   %y ls=%p (ls->mutex=%p%(y)\n", 
-                       mutex->mutexp, ls,
-                       mx->mutexp, mx->mutexp);
-        if (check_cycle_inner(mx, mx->lockdep))
-           return True;
-      }
-      ((Mutex*)mutex)->mark = MARK_DONE;
-        
-      return False;
+         VG_(printf)("   %y ls=%p (ls->mutex=%p%(y)\n", 
+                     mutex->mutexp, ls,
+                     mx->mutexp, mx->mutexp);
+      if (check_cycle_inner(mx, mx->lockdep))
+         return True;
    }
+   ((Mutex*)mutex)->mark = MARK_DONE;
+   
+   return False;
+}
+
+static Bool check_cycle(const Mutex *start, const LockSet* lockset)
+{
 
    graph_mark += 2;            /* clear all marks */
 
@@ -1581,18 +1582,18 @@ static void set_mutex_state(Mutex *mutex, MutexState state, ThreadId tid)
 /*--- Setting and checking permissions.                    ---*/
 /*------------------------------------------------------------*/
 
+/* only clean up dead mutexes */
+static
+Bool cleanmx(Mutex *mx) {
+   return mx->state == MxDead;
+}
+
 static
 void set_address_range_state ( Addr a, UInt len /* in bytes */, 
                                VgeInitStatus status )
 {
    Addr end;
 
-   /* only clean up dead mutexes */
-   Bool cleanmx(Mutex *mx) {
-      return mx->state == MxDead;
-   }
-
-
 #  if DEBUG_MAKE_ACCESSES
    VG_(printf)("make_access: 0x%x, %u, status=%u\n", a, len, status);
 #  endif
@@ -1870,6 +1871,16 @@ void* SK_(calloc) ( Int nmemb, Int size )
                               /*is_zeroed*/True );
 }
 
+static ThreadId deadmx_tid;
+
+static
+Bool deadmx(Mutex *mx) {
+   if (mx->state != MxDead)
+      set_mutex_state(mx, MxDead, deadmx_tid);
+   
+   return False;
+}
+
 static
 void die_and_free_mem ( ThreadId tid, HG_Chunk* hc,
                         HG_Chunk** prev_chunks_next_ptr )
@@ -1877,13 +1888,6 @@ void die_and_free_mem ( ThreadId tid, HG_Chunk* hc,
    Addr start = hc->data;
    Addr end   = start + hc->size;
 
-   Bool deadmx(Mutex *mx) {
-      if (mx->state != MxDead)
-         set_mutex_state(mx, MxDead, tid);
-
-      return False;
-   }
-
    /* Remove hc from the malloclist using prev_chunks_next_ptr to
       avoid repeating the hash table lookup.  Can't remove until at least
       after free and free_mismatch errors are done because they use
@@ -1908,6 +1912,7 @@ void die_and_free_mem ( ThreadId tid, HG_Chunk* hc,
       freechunkptr = 0;
 
    /* mark all mutexes in range dead */
+   deadmx_tid = tid;
    find_mutex_range(start, end, deadmx);
 }
 
@@ -2378,25 +2383,20 @@ void clear_HelgrindError ( HelgrindError* err_extra )
 /* Describe an address as best you can, for error messages,
    putting the result in ai. */
 
+/* Callback for searching malloc'd and free'd lists */
+static Bool addr_is_in_block(VgHashNode *node, void *ap)
+{
+   HG_Chunk* hc2 = (HG_Chunk*)node;
+   Addr a = *(Addr *)ap;
+   
+   return (hc2->data <= a && a < hc2->data + hc2->size);
+}
+
 static void describe_addr ( Addr a, AddrInfo* ai )
 {
    HG_Chunk* hc;
    Int i;
 
-   /* Nested functions, yeah.  Need the lexical scoping of 'a'. */ 
-
-   /* Closure for searching thread stacks */
-   Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
-   {
-      return (stack_min <= a && a <= stack_max);
-   }
-   /* Closure for searching malloc'd and free'd lists */
-   Bool addr_is_in_block(VgHashNode *node)
-   {
-      HG_Chunk* hc2 = (HG_Chunk*)node;
-      return (hc2->data <= a && a < hc2->data + hc2->size);
-   }
-
    /* Search for it in segments */
    {
       const SegInfo *seg;
@@ -2431,7 +2431,7 @@ static void describe_addr ( Addr a, AddrInfo* ai )
    }
 
    /* Search for a currently malloc'd block which might bracket it. */
-   hc = (HG_Chunk*)VG_(HT_first_match)(hg_malloc_list, addr_is_in_block);
+   hc = (HG_Chunk*)VG_(HT_first_match)(hg_malloc_list, addr_is_in_block, &a);
    if (NULL != hc) {
       ai->akind      = Mallocd;
       ai->blksize    = hc->size;
index b5d08922925c639bd681688788864c80f762ebdc..2cd6637b69d6d55781bbe71ccef6a02b3e63075a 100644 (file)
@@ -360,7 +360,8 @@ extern ThreadId VG_(get_current_tid)           ( void );
 /* Searches through all thread's stacks to see if any match.  Returns
    VG_INVALID_THREADID if none match. */
 extern ThreadId VG_(first_matching_thread_stack)
-                        ( Bool (*p) ( Addr stack_min, Addr stack_max ));
+                        ( Bool (*p) ( Addr stack_min, Addr stack_max, void* d ),
+                          void* d );
 
 
 /*====================================================================*/
@@ -1713,14 +1714,17 @@ extern VgHashNode* VG_(HT_get_node) ( VgHashTable t, UInt key,
 extern VgHashNode** VG_(HT_to_array) ( VgHashTable t, /*OUT*/ UInt* n_shadows );
 
 /* Returns first node that matches predicate `p', or NULL if none do.
-   Extra arguments can be implicitly passed to `p' using nested functions;
-   see memcheck/mc_errcontext.c for an example. */
+   Extra arguments can be implicitly passed to `p' using `d' which is an
+   opaque pointer passed to `p' each time it is called. */
 extern VgHashNode* VG_(HT_first_match) ( VgHashTable t,
-                                         Bool (*p)(VgHashNode*) );
-
-/* Applies a function f() once to each node.  Again, nested functions
-   can be very useful. */
-extern void VG_(HT_apply_to_all_nodes)( VgHashTable t, void (*f)(VgHashNode*) );
+                                         Bool (*p)(VgHashNode*, void*),
+                                         void* d );
+
+/* Applies a function f() once to each node.  Again, `d' can be used
+   to pass extra information to the function. */
+extern void VG_(HT_apply_to_all_nodes)( VgHashTable t,
+                                        void (*f)(VgHashNode*, void*),
+                                        void* d );
 
 /* Destroy a table. */
 extern void VG_(HT_destruct) ( VgHashTable t );
index 584da1089ccef464c68127a68d68135ea3eeea98..44b865a5de09263dce4429d69b25febd036aeb53 100644 (file)
@@ -856,10 +856,9 @@ static Census censi[MAX_N_CENSI];
 static UInt   curr_census = 0;
 
 // Must return False so that all stacks are traversed
-static UInt count_stack_size_counter;
-static Bool count_stack_size( Addr stack_min, Addr stack_max )
+static Bool count_stack_size( Addr stack_min, Addr stack_max, void *cp )
 {
-   count_stack_size_counter += (stack_max - stack_min);
+   *(UInt *)cp  += (stack_max - stack_min);
    return False;
 }
 
@@ -1079,10 +1078,9 @@ static void hp_census(void)
 
    // Stack(s) ---------------------------------------------------------
    if (clo_stacks) {
-      count_stack_size_counter = sigstacks_space;
+      census->stacks_space = sigstacks_space;
       // slightly abusing this function
-      VG_(first_matching_thread_stack)( count_stack_size );
-      census->stacks_space = count_stack_size_counter;
+      VG_(first_matching_thread_stack)( count_stack_size, &census->stacks_space );
       i++;
    }
 
index 45c0ec1c0500656f9c5036f42075ba88151d6e8d..93daf7b49f5cdb1c0da961bb5eec59c867dac070 100644 (file)
@@ -116,14 +116,15 @@ static void add_to_freed_queue ( MAC_Chunk* mc )
 }
 
 /* Return the first shadow chunk satisfying the predicate p. */
-MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk) ( Bool (*p)(MAC_Chunk*) )
+MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk) ( Bool (*p)(MAC_Chunk*, void*),
+                                                  void* d )
 {
    MAC_Chunk* mc;
 
    /* No point looking through freed blocks if we're not keeping
       them around for a while... */
    for (mc = freed_list_start; mc != NULL; mc = mc->next)
-      if (p(mc))
+      if (p(mc, d))
          return mc;
 
    return NULL;
@@ -439,24 +440,26 @@ void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed)
    
 }
 
+static void destroy_mempool_nuke_chunk(VgHashNode *node, void *d)
+{
+   MAC_Chunk *mc = (MAC_Chunk *)node;
+   MAC_Mempool *mp = (MAC_Mempool *)d;
+  
+   /* Note: ban redzones again -- just in case user de-banned them
+      with a client request... */
+   MAC_(ban_mem_heap)(mc->data-mp->rzB, mp->rzB );
+   MAC_(die_mem_heap)(mc->data, mc->size );
+   MAC_(ban_mem_heap)(mc->data+mc->size, mp->rzB );
+}
+
 void MAC_(destroy_mempool)(Addr pool)
 {
-   MAC_Mempool*  mp;
+   MAC_Mempool* mp;
    MAC_Mempool** prev_next;
 
-   void nuke_chunk(VgHashNode *node)
-   {
-      MAC_Chunk *mc = (MAC_Chunk *)node;
-
-      /* Note: ban redzones again -- just in case user de-banned them
-         with a client request... */
-      MAC_(ban_mem_heap)(mc->data-mp->rzB, mp->rzB );
-      MAC_(die_mem_heap)(mc->data, mc->size );
-      MAC_(ban_mem_heap)(mc->data+mc->size, mp->rzB );
-   }
-
-   mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list), (UInt)pool,
-                                        (VgHashNode***)&prev_next );
+   mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list),
+                                         (UInt)pool,
+                                         (VgHashNode***)&prev_next );
 
    if (mp == NULL) {
       ThreadId      tid = VG_(get_current_or_recent_tid)();
@@ -466,7 +469,7 @@ void MAC_(destroy_mempool)(Addr pool)
    }
 
    *prev_next = mp->next;
-   VG_(HT_apply_to_all_nodes)(mp->chunks, nuke_chunk);
+   VG_(HT_apply_to_all_nodes)(mp->chunks, destroy_mempool_nuke_chunk, mp);
    VG_(HT_destruct)(mp->chunks);
 
    VG_(free)(mp);
@@ -520,26 +523,38 @@ void MAC_(mempool_free)(Addr pool, Addr addr)
    die_and_free_mem(mc, prev_chunk, mp->rzB);
 }
 
+typedef
+   struct {
+      UInt nblocks;
+     UInt nbytes;
+   }
+   MallocStats;
+
+static void malloc_stats_count_chunk(VgHashNode* node, void* d) {
+   MAC_Chunk* mc = (MAC_Chunk*)node;
+   MallocStats *ms = (MallocStats *)d;
+
+   ms->nblocks ++;
+   ms->nbytes  += mc->size;
+}
+
 void MAC_(print_malloc_stats) ( void )
 {
-   UInt nblocks = 0, nbytes = 0;
+   MallocStats ms;
+  
+   ms.nblocks = 0;
+   ms.nbytes = 0;
    
    /* Mmm... more lexical scoping */
-   void count_one_chunk(VgHashNode* node) {
-      MAC_Chunk* mc = (MAC_Chunk*)node;
-      nblocks ++;
-      nbytes  += mc->size;
-   }
-
    if (VG_(clo_verbosity) == 0)
       return;
 
    /* Count memory still in use. */
-   VG_(HT_apply_to_all_nodes)(MAC_(malloc_list), count_one_chunk);
+   VG_(HT_apply_to_all_nodes)(MAC_(malloc_list), malloc_stats_count_chunk, &ms);
 
    VG_(message)(Vg_UserMsg, 
                 "malloc/free: in use at exit: %d bytes in %d blocks.",
-                nbytes, nblocks);
+                ms.nbytes, ms.nblocks);
    VG_(message)(Vg_UserMsg, 
                 "malloc/free: %d allocs, %d frees, %u bytes allocated.",
                 cmalloc_n_mallocs,
index 8e1a7b8a4e39fe7e005997eaca0df19b1f8d282d..f2c8dc492dcc026c6ed8ed2238536f18b2ad3f1e 100644 (file)
@@ -343,7 +343,29 @@ void MAC_(pp_shared_SkinError) ( Error* err )
 /* Additional description function for describe_addr();  used by
    MemCheck for user blocks, which Addrcheck doesn't support. */
 Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai ) = NULL;
-   
+
+/* Callback for searching thread stacks */
+static Bool addr_is_in_bounds(Addr stack_min, Addr stack_max, void *ap)
+{
+   Addr a = *(Addr *)ap;
+  
+   return (stack_min <= a && a <= stack_max);
+}
+
+/* Callback for searching free'd list */
+static Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc, void *ap)
+{
+   Addr a = *(Addr *)ap;
+  
+   return VG_(addr_is_in_block)( a, mc->data, mc->size );
+}
+
+/* Callback for searching malloc'd lists */
+static Bool addr_is_in_HashNode(VgHashNode* sh_ch, void *ap)
+{
+   return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch, ap );
+}
+
 /* Describe an address as best you can, for error messages,
    putting the result in ai. */
 static void describe_addr ( Addr a, AddrInfo* ai )
@@ -351,38 +373,20 @@ static void describe_addr ( Addr a, AddrInfo* ai )
    MAC_Chunk* sc;
    ThreadId   tid;
 
-   /* Nested functions, yeah.  Need the lexical scoping of 'a'. */
-
-   /* Closure for searching thread stacks */
-   Bool addr_is_in_bounds(Addr stack_min, Addr stack_max)
-   {
-      return (stack_min <= a && a <= stack_max);
-   }
-   /* Closure for searching free'd list */
-   Bool addr_is_in_MAC_Chunk(MAC_Chunk* mc)
-   {
-      return VG_(addr_is_in_block)( a, mc->data, mc->size );
-   }
-   /* Closure for searching malloc'd lists */
-   Bool addr_is_in_HashNode(VgHashNode* sh_ch)
-   {
-      return addr_is_in_MAC_Chunk( (MAC_Chunk*)sh_ch );
-   }
-
    /* Perhaps it's a user-def'd block ?  (only check if requested, though) */
    if (NULL != MAC_(describe_addr_supp)) {
       if (MAC_(describe_addr_supp)( a, ai ))
          return;
    }
    /* Perhaps it's on a thread's stack? */
-   tid = VG_(first_matching_thread_stack)(addr_is_in_bounds);
+   tid = VG_(first_matching_thread_stack)(addr_is_in_bounds, &a);
    if (tid != VG_INVALID_THREADID) {
       ai->akind     = Stack;
       ai->stack_tid = tid;
       return;
    }
    /* Search for a recently freed block which might bracket it. */
-   sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk);
+   sc = MAC_(first_matching_freed_MAC_Chunk)(addr_is_in_MAC_Chunk, &a);
    if (NULL != sc) {
       ai->akind      = Freed;
       ai->blksize    = sc->size;
@@ -391,7 +395,7 @@ static void describe_addr ( Addr a, AddrInfo* ai )
       return;
    }
    /* Search for a currently malloc'd block which might bracket it. */
-   sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode);
+   sc = (MAC_Chunk*)VG_(HT_first_match)(MAC_(malloc_list), addr_is_in_HashNode, &a);
    if (NULL != sc) {
       ai->akind      = Mallocd;
       ai->blksize    = sc->size;
index 1ae789f4f2ac0384af0d3da54a6b62bfb09cf9bf..d574203b955992374a429901c339de86c6d6b7c3 100644 (file)
@@ -341,7 +341,7 @@ extern void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr pool );
 
 extern void MAC_(pp_shared_SkinError)      ( Error* err);
 
-extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*) );
+extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*, void*), void* d );
 
 extern void MAC_(common_pre_clo_init) ( void );
 extern void MAC_(common_fini)         ( void (*leak_check)(void) );
index 959223774105b886965ea203a48f89725595ab01..65b5f650fc8868220df1490b826e9774869119d3 100644 (file)
@@ -124,6 +124,14 @@ void MC_(show_client_block_stats) ( void )
    );
 }
 
+static Bool find_addr(VgHashNode* sh_ch, void* ap)
+{
+  MAC_Chunk *m = (MAC_Chunk*)sh_ch;
+  Addr a = *(Addr*)ap;
+
+  return VG_(addr_is_in_block)(a, m->data, m->size);
+}
+
 Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai )
 {
    UInt i;
@@ -144,13 +152,7 @@ Bool MC_(client_perm_maybe_describe)( Addr a, AddrInfo* ai )
             if(mp->chunks != NULL) {
                MAC_Chunk *mc;
 
-               Bool find_addr(VgHashNode* sh_ch)
-               {
-                  MAC_Chunk *m = (MAC_Chunk*)sh_ch;
-                  return VG_(addr_is_in_block)(a, m->data, m->size);
-               }
-
-               mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr);
+               mc = (MAC_Chunk*)VG_(HT_first_match)(mp->chunks, find_addr, &a);
                if(mc != NULL) {
                   ai->akind = UserG;
                   ai->blksize = mc->size;
index dc5c898ab6bd10af75f3abf224f8ff850ac4ddf4..321be66a82d026a3344cdd05175ccdf48af803be 100644 (file)
@@ -58,8 +58,10 @@ MC_(helper_value_check4_fail):
        call    MC_(helperc_value_check4_fail)
        popal
        ret
+        
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
 
 ##--------------------------------------------------------------------##
 ##--- end                                            mc_helpers.S ---##
 ##--------------------------------------------------------------------##
-