|
From: Tom H. <th...@cy...> - 2004-06-27 17:37:34
|
CVS commit by thughes:
Removed all uses of nested functions as they only work with gcc and
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.
M +6 -5 coregrind/stage1.c 1.12 [POSSIBLY UNSAFE: printf]
M +53 -44 coregrind/ume.c 1.10
M +7 -0 coregrind/vg_cpuid.S 1.2
M +3 -1 coregrind/vg_dispatch.S 1.17
M +8 -4 coregrind/vg_hashtable.c 1.9
M +4 -1 coregrind/vg_helpers.S 1.33
M +47 -43 coregrind/vg_main.c 1.166 [POSSIBLY UNSAFE: printf]
M +11 -7 coregrind/vg_mylibc.c 1.75
M +4 -3 coregrind/vg_scheduler.c 1.154
M +36 -31 coregrind/vg_symtypes.c 1.6 [POSSIBLY UNSAFE: printf]
M +4 -1 coregrind/vg_syscall.S 1.13
M +18 -9 coregrind/vg_transtab.c 1.28
M +3 -0 coregrind/x86/ume_entry.S 1.3
M +55 -55 helgrind/hg_main.c 1.77
M +11 -7 include/vg_skin.h.base 1.23
M +4 -6 massif/ms_main.c 1.11
M +41 -26 memcheck/mac_malloc_wrappers.c 1.12
M +26 -22 memcheck/mac_needs.c 1.28
M +1 -1 memcheck/mac_shared.h 1.19
M +9 -7 memcheck/mc_clientreqs.c 1.21
M +3 -1 memcheck/mc_helpers.S 1.9
--- valgrind/coregrind/stage1.c #1.11:1.12
@@ -157,4 +157,10 @@ static void *fix_auxv(void *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)
{
@@ -194,9 +200,4 @@ static void hoops(void)
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);
--- valgrind/coregrind/ume.c #1.9:1.10
@@ -145,23 +145,25 @@ void foreach_map(int (*fn)(void *start,
}
-/* 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;
+static char *fillgap_addr;
+static char *fillgap_end;
- int fillgap(void *segstart, void *segend, const char *perm, off_t off,
+static int fillgap(void *segstart, void *segend, const char *perm, off_t off,
int maj, int min, int ino) {
- if (segstart >= end)
+ if ((char *)segstart >= fillgap_end)
return 0;
- if ((char *)segstart > addr)
- mmap(addr, (char *)segstart-addr, PROT_NONE, MAP_FIXED|MAP_PRIVATE,
- padfile, 0);
- addr = segend;
+ 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];
if (padfile == -1) {
@@ -177,18 +179,18 @@ void as_pad(void *start, void *end)
}
- 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,
+static void *killpad_start;
+static void *killpad_end;
+
+static int killpad(void *segstart, void *segend, const char *perm, off_t off,
int maj, int min, int ino) {
void *b, *e;
@@ -197,14 +199,14 @@ void as_unpad(void *start, void *end)
return 1;
- if (segend <= start || segstart >= end)
+ if (segend <= killpad_start || segstart >= killpad_end)
return 1;
- if (segstart <= start)
- b = start;
+ if (segstart <= killpad_start)
+ b = killpad_start;
else
b = segstart;
- if (segend >= end)
- e = end;
+ if (segend >= killpad_end)
+ e = killpad_end;
else
e = segend;
@@ -213,9 +215,16 @@ void as_unpad(void *start, void *end)
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);
}
--- valgrind/coregrind/vg_cpuid.S #1.1:1.2
@@ -76,2 +76,9 @@
popl %ebp
ret
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
+##--------------------------------------------------------------------##
+##--- end vg_cpuid.S ---##
+##--------------------------------------------------------------------##
--- valgrind/coregrind/vg_dispatch.S #1.16:1.17
@@ -223,5 +223,7 @@
.byte 0
.text
-
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
##--------------------------------------------------------------------##
--- valgrind/coregrind/vg_hashtable.c #1.8:1.9
@@ -134,5 +134,7 @@ VgHashNode** VG_(HT_to_array) ( VgHashTa
/* 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;
@@ -141,5 +143,5 @@ VgHashNode* VG_(HT_first_match) ( VgHash
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;
@@ -147,5 +149,7 @@ VgHashNode* VG_(HT_first_match) ( VgHash
}
-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;
@@ -154,5 +158,5 @@ void VG_(HT_apply_to_all_nodes)( VgHashT
for (i = 0; i < VG_N_CHAINS; i++) {
for (node = table[i]; node != NULL; node = node->next) {
- f(node);
+ f(node, d);
}
}
--- valgrind/coregrind/vg_helpers.S #1.32:1.33
@@ -724,5 +724,8 @@
1: ud2
jmp 1b
-
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
+
##--------------------------------------------------------------------##
##--- end vg_helpers.S ---##
--- valgrind/coregrind/vg_main.c #1.165:1.166
@@ -765,8 +765,11 @@ static void get_command_line( int argc,
/* 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;
@@ -775,5 +778,5 @@ static void scan_colsep(char *colsep, in
if (colsep == NULL ||
*colsep == '\0')
- return;
+ return False;
entry = cp = colsep;
@@ -787,5 +790,5 @@ static void scan_colsep(char *colsep, in
*cp = '\0';
if ((*func)(entry))
- end = 1;
+ return True;
*cp = save;
entry = cp+1;
@@ -793,4 +796,13 @@ static void scan_colsep(char *colsep, in
cp++;
} while(!end);
+
+ return False;
+}
+
+static Bool contains(const char *p) {
+ if (VG_STREQ(p, VG_(libdir))) {
+ return True;
+ }
+ return False;
}
@@ -856,20 +868,9 @@ static char **fix_environment(char **ori
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);
@@ -1203,14 +1204,8 @@ static Addr setup_client_stack(char **or
/*====================================================================*/
-static const char* find_executable(const char* exec)
-{
- vg_assert(NULL != exec);
- if (strchr(exec, '/') == NULL) {
- /* no '/' - we need to search the path */
- char *path = getenv("PATH");
- int pathlen = path ? strlen(path) : 0;
+static const char* executable_name;
- int match_exe(const char *entry) {
- char buf[pathlen + strlen(entry) + 3];
+static Bool match_executable(const char *entry) {
+ char buf[strlen(entry) + strlen(executable_name) + 2];
/* empty PATH element means . */
@@ -1218,16 +1213,24 @@ static const char* find_executable(const
entry = ".";
- snprintf(buf, sizeof(buf), "%s/%s", entry, exec);
+ snprintf(buf, sizeof(buf), "%s/%s", entry, executable_name);
if (access(buf, R_OK|X_OK) == 0) {
- exec = strdup(buf);
- vg_assert(NULL != exec);
- return 1;
- }
- return 0;
+ executable_name = strdup(buf);
+ vg_assert(NULL != executable_name);
+ return True;
}
- scan_colsep(path, match_exe);
+ return False;
+}
+
+static const char* find_executable(const char* exec)
+{
+ vg_assert(NULL != exec);
+ executable_name = exec;
+ if (strchr(executable_name, '/') == NULL) {
+ /* no '/' - we need to search the path */
+ char *path = getenv("PATH");
+ scan_colsep(path, match_executable);
}
- return exec;
+ return executable_name;
}
@@ -2628,4 +2631,11 @@ void VG_(do_sanity_checks) ( Bool force_
/*====================================================================*/
+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)
{
@@ -2676,10 +2686,4 @@ int main(int argc, char **argv)
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);
--- valgrind/coregrind/vg_mylibc.c #1.74:1.75
@@ -731,15 +731,19 @@ UInt VG_(printf) ( const char *format, .
}
-
/* 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);
--- valgrind/coregrind/vg_scheduler.c #1.153:1.154
@@ -166,5 +166,6 @@ Bool VG_(is_valid_or_empty_tid) ( 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;
@@ -177,5 +178,5 @@ ThreadId VG_(first_matching_thread_stack
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
@@ -187,5 +188,5 @@ ThreadId VG_(first_matching_thread_stack
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;
}
--- valgrind/coregrind/vg_symtypes.c #1.5:1.6
@@ -662,4 +662,31 @@ static inline Bool is_followable(SymType
}
+/* 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 */
@@ -674,32 +701,10 @@ Char *VG_(describe_addr)(ThreadId tid, A
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();
@@ -1014,5 +1019,5 @@ Char *VG_(describe_addr)(ThreadId tid, A
found->container = found->container->container;
} else {
- bprintf(addbuf, "&(");
+ bprintf(describe_addr_addbuf, "&(");
ptr = False;
}
@@ -1026,11 +1031,11 @@ Char *VG_(describe_addr)(ThreadId tid, A
*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);
}
}
@@ -1044,7 +1049,7 @@ Char *VG_(describe_addr)(ThreadId tid, A
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 */
--- valgrind/coregrind/vg_syscall.S #1.12:1.13
@@ -118,5 +118,8 @@
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 ---##
--- valgrind/coregrind/vg_transtab.c #1.27:1.28
@@ -166,17 +166,26 @@ 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_sector(Int s, Addr base, UInt len)
-{
- void unchain_site(Addr a) {
+void unchain_site_for_sector(Addr a) {
Addr jmp = VG_(get_jmp_dest)(a);
- if (jmp >= base && jmp < (base+len))
+ if (jmp >= sector_base && jmp < (sector_base+sector_len))
VG_(unchain_jumpsite)(a);
- }
- void _unchain_tce(TCEntry *tce) {
- for_each_jumpsite(tce, unchain_site);
- }
+}
- for_each_tc(s, _unchain_tce);
+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)
+{
+ sector_base = base;
+ sector_len = len;
+
+ for_each_tc(s, unchain_tce_for_sector);
}
--- valgrind/coregrind/x86/ume_entry.S #1.2:1.3
@@ -37,2 +37,5 @@
.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
--- valgrind/helgrind/hg_main.c #1.76:1.77
@@ -1405,8 +1405,6 @@ static void find_mutex_range(Addr start,
#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;
@@ -1435,5 +1433,8 @@ static Bool check_cycle(const Mutex *sta
return False;
- }
+}
+
+static Bool check_cycle(const Mutex *start, const LockSet* lockset)
+{
graph_mark += 2; /* clear all marks */
@@ -1582,4 +1583,10 @@ static void set_mutex_state(Mutex *mutex
/*------------------------------------------------------------*/
+/* 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 */,
@@ -1588,10 +1595,4 @@ void set_address_range_state ( Addr a, U
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);
@@ -1871,4 +1872,14 @@ void* SK_(calloc) ( Int nmemb, Int size
}
+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,
@@ -1878,11 +1889,4 @@ void die_and_free_mem ( ThreadId tid, HG
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
@@ -1909,4 +1913,5 @@ void die_and_free_mem ( ThreadId tid, HG
/* mark all mutexes in range dead */
+ deadmx_tid = tid;
find_mutex_range(start, end, deadmx);
}
@@ -2379,4 +2384,13 @@ void clear_HelgrindError ( HelgrindError
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 )
{
@@ -2384,18 +2398,4 @@ static void describe_addr ( Addr a, Addr
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 */
{
@@ -2432,5 +2432,5 @@ static void describe_addr ( Addr a, Addr
/* 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;
--- valgrind/include/vg_skin.h.base #1.22:1.23
@@ -361,5 +361,6 @@
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 );
@@ -1714,12 +1715,15 @@
/* 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*) );
+ Bool (*p)(VgHashNode*, void*),
+ void* d );
-/* 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*) );
+/* 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. */
--- valgrind/massif/ms_main.c #1.10:1.11
@@ -857,8 +857,7 @@ 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;
}
@@ -1080,8 +1079,7 @@ 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++;
}
--- valgrind/memcheck/mac_malloc_wrappers.c #1.11:1.12
@@ -117,5 +117,6 @@ static void add_to_freed_queue ( MAC_Chu
/* 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;
@@ -124,5 +125,5 @@ MAC_Chunk* MAC_(first_matching_freed_MAC
them around for a while... */
for (mc = freed_list_start; mc != NULL; mc = mc->next)
- if (p(mc))
+ if (p(mc, d))
return mc;
@@ -440,12 +441,8 @@ void MAC_(create_mempool)(Addr pool, UIn
}
-void MAC_(destroy_mempool)(Addr pool)
+static void destroy_mempool_nuke_chunk(VgHashNode *node, void *d)
{
- MAC_Mempool* mp;
- MAC_Mempool** prev_next;
-
- void nuke_chunk(VgHashNode *node)
- {
MAC_Chunk *mc = (MAC_Chunk *)node;
+ MAC_Mempool *mp = (MAC_Mempool *)d;
/* Note: ban redzones again -- just in case user de-banned them
@@ -454,7 +451,13 @@ void MAC_(destroy_mempool)(Addr pool)
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,
+void MAC_(destroy_mempool)(Addr pool)
+{
+ MAC_Mempool* mp;
+ MAC_Mempool** prev_next;
+
+ mp = (MAC_Mempool*)VG_(HT_get_node) ( MAC_(mempool_list),
+ (UInt)pool,
(VgHashNode***)&prev_next );
@@ -467,5 +470,5 @@ 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);
@@ -521,24 +524,36 @@ void MAC_(mempool_free)(Addr pool, Addr
}
+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;
- /* Mmm... more lexical scoping */
- void count_one_chunk(VgHashNode* node) {
- MAC_Chunk* mc = (MAC_Chunk*)node;
- nblocks ++;
- nbytes += mc->size;
- }
+ ms.nblocks = 0;
+ ms.nbytes = 0;
+ /* Mmm... more lexical scoping */
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.",
--- valgrind/memcheck/mac_needs.c #1.27:1.28
@@ -345,4 +345,26 @@ void MAC_(pp_shared_SkinError) ( Error*
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. */
@@ -352,22 +374,4 @@ static void describe_addr ( Addr a, Addr
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)) {
@@ -376,5 +380,5 @@ static void describe_addr ( Addr a, Addr
}
/* 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;
@@ -383,5 +387,5 @@ static void describe_addr ( Addr a, Addr
}
/* 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;
@@ -392,5 +396,5 @@ static void describe_addr ( Addr a, Addr
}
/* 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;
--- valgrind/memcheck/mac_shared.h #1.18:1.19
@@ -342,5 +342,5 @@ extern void MAC_(record_illegal_mempool_
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 );
--- valgrind/memcheck/mc_clientreqs.c #1.20:1.21
@@ -125,4 +125,12 @@ 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 )
{
@@ -145,11 +153,5 @@ Bool MC_(client_perm_maybe_describe)( Ad
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;
--- valgrind/memcheck/mc_helpers.S #1.8:1.9
@@ -59,7 +59,9 @@
popal
ret
+
+/* Let the linker know we don't need an executable stack */
+.section .note.GNU-stack,"",@progbits
##--------------------------------------------------------------------##
##--- end mc_helpers.S ---##
##--------------------------------------------------------------------##
-
|