|
From: <sv...@va...> - 2005-09-19 17:12:37
|
Author: sewardj
Date: 2005-09-19 18:12:04 +0100 (Mon, 19 Sep 2005)
New Revision: 4681
Log:
A whole stack of changes needed to make memcheck work with the new
address space manager.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_debuginfo/symtab.c
branches/ASPACEM/coregrind/m_main.c
branches/ASPACEM/coregrind/m_mallocfree.c
branches/ASPACEM/coregrind/m_scheduler/scheduler.c
branches/ASPACEM/coregrind/m_signals.c
branches/ASPACEM/coregrind/m_stacktrace.c
branches/ASPACEM/coregrind/pub_core_aspacemgr.h
branches/ASPACEM/coregrind/pub_core_scheduler.h
branches/ASPACEM/include/pub_tool_aspacemgr.h
branches/ASPACEM/memcheck/mac_leakcheck.c
branches/ASPACEM/memcheck/mc_main.c
Modified: branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-19 08:08:4=
6 UTC (rev 4680)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-19 17:12:0=
4 UTC (rev 4681)
@@ -1767,18 +1767,26 @@
}
=20
/* Collect up the start addresses of all non-free, non-resvn segments.
- The interface is a bit strange. You have to call it twice. If
- 'starts' is NULL, the number of such segments is calculated and
- written to *nStarts. If 'starts' is non-NULL, it should point to
- an array of size *nStarts, and the segment start addresses are
- written at starts[0 .. *nStarts-1]. In the latter case, the number
- of required slots is recalculated, and the function asserts if this
- is not equal to *nStarts. */
+ The interface is a bit strange in order to avoid potential
+ segment-creation races caused by dynamic allocation of the result
+ buffer *starts.
=20
-void VG_(am_get_segment_starts)( Addr* starts, Int* nStarts )
+ The function first computes how many entries in the result
+ buffer *starts will be needed. If this number <=3D nStarts,
+ they are placed in starts[0..], and the number is returned.
+ If nStarts is not large enough, nothing is written to
+ starts[0..], and the negation of the size is returned.
+
+ Correct use of this function may mean calling it multiple times in
+ order to establish a suitably-sized buffer. */
+
+Int VG_(am_get_segment_starts)( Addr* starts, Int nStarts )
{
Int i, j, nSegs;
=20
+ /* don't pass dumbass arguments */
+ aspacem_assert(nStarts >=3D 0);
+
nSegs =3D 0;
for (i =3D 0; i < nsegments_used; i++) {
if (nsegments[i].kind =3D=3D SkFree || nsegments[i].kind =3D=3D Sk=
Resvn)
@@ -1786,15 +1794,14 @@
nSegs++;
}
=20
- if (starts =3D=3D NULL) {
- /* caller just wants to know how many segments there are. */
- *nStarts =3D nSegs;
- return;
+ if (nSegs > nStarts) {
+ /* The buffer isn't big enough. Tell the caller how big it needs
+ to be. */
+ return -nSegs;
}
=20
- /* otherwise, caller really is after the segments. */
- /* If this assertion fails, the passed-in *nStarts is incorrect. */
- aspacem_assert(*nStarts =3D=3D nSegs);
+ /* There's enough space. So write into the result buffer. */
+ aspacem_assert(nSegs <=3D nStarts);
=20
j =3D 0;
for (i =3D 0; i < nsegments_used; i++) {
@@ -1805,6 +1812,7 @@
}
=20
aspacem_assert(j =3D=3D nSegs); /* this should not fail */
+ return nSegs;
}
=20
=20
@@ -3090,7 +3098,16 @@
return sres;
}
=20
+/* Really just a wrapper around VG_(am_mmap_anon_float_valgrind). */
=20
+void* VG_(am_shadow_alloc)(SizeT size)
+{
+ SysRes sres =3D VG_(am_mmap_anon_float_valgrind)( size );
+ return sres.isError ? NULL : (void*)sres.val;
+}
+
+
+
/* Map a file at an unconstrained address for V, and update the
segment array accordingly. This is used by V for transiently
mapping in object files to read their debug info. */
Modified: branches/ASPACEM/coregrind/m_debuginfo/symtab.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_debuginfo/symtab.c 2005-09-19 08:08:46 U=
TC (rev 4680)
+++ branches/ASPACEM/coregrind/m_debuginfo/symtab.c 2005-09-19 17:12:04 U=
TC (rev 4681)
@@ -158,7 +158,7 @@
}
=20
if (!found) break;
- unload_symbols( curr->start, 1 );
+ unload_symbols( curr->start, curr->size );
=20
}
}
@@ -207,7 +207,11 @@
=20
void VG_(di_notify_mprotect)( Addr a, SizeT len, UInt prot )
{
- if (!(prot & VKI_PROT_EXEC))
+ Bool exe_ok =3D toBool(prot & VKI_PROT_EXEC);
+# if defined(VGP_x86_linux)
+ exe_ok =3D exe_ok || toBool(prot & VKI_PROT_READ);
+# endif
+ if (!exe_ok)
nuke_syms_in_range(a, len);
}
=20
Modified: branches/ASPACEM/coregrind/m_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_main.c 2005-09-19 08:08:46 UTC (rev 4680=
)
+++ branches/ASPACEM/coregrind/m_main.c 2005-09-19 17:12:04 UTC (rev 4681=
)
@@ -920,7 +920,7 @@
=20
// See pub_{core,tool}_options.h for explanations of all these.
=20
-static void usage ( Bool debug_help )
+static void usage_NORETURN ( Bool debug_help )
{
Char* usage1 =3D=20
"usage: valgrind --tool=3D<toolname> [options] prog-and-args\n"
@@ -2035,6 +2035,40 @@
/*=3D=3D=3D main() =
=3D=3D=3D*/
/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
=20
+/* TODO: GIVE THIS A PROPER HOME
+ TODO: MERGE THIS WITH DUPLICATE IN mac_leakcheck.c
+ Extract from aspacem a vector of the current segment start
+ addresses. The vector is dynamically allocated and should be freed
+ by the caller when done. REQUIRES m_mallocfree to be running.
+ Writes the number of addresses required into *n_acquired. */
+
+static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
+{
+ Addr* starts;
+ Int n_starts, r;
+
+ n_starts =3D 1;
+ while (True) {
+ starts =3D VG_(malloc)( n_starts * sizeof(Addr) );
+ if (starts =3D=3D NULL)
+ break;
+ r =3D VG_(am_get_segment_starts)( starts, n_starts );
+ if (r >=3D 0)
+ break;
+ VG_(free)(starts);
+ n_starts *=3D 2;
+ }
+
+ if (starts =3D=3D NULL) {
+ *n_acquired =3D 0;
+ return NULL;
+ }
+
+ *n_acquired =3D r;
+ return starts;
+}
+
+
/*
This code decides on the layout of the client and Valgrind address
spaces, loads valgrind.so and the tool.so into the valgrind part,
@@ -2098,6 +2132,7 @@
Addr initial_client_IP;
Addr initial_client_SP;
Addr clstack_top;
+ SizeT clstack_max_size;
UInt* client_auxv;
Int loglevel, i;
struct vki_rlimit zero =3D { 0, 0 };
@@ -2307,14 +2342,14 @@
void* init_sp =3D argv - 1;
SizeT m1 =3D 1024 * 1024;
SizeT m8 =3D 8 * m1;
- SizeT stack_max_size =3D (SizeT)VG_(client_rlimit_stack).rlim_cur;
- if (stack_max_size < m1) stack_max_size =3D m1;
- if (stack_max_size > m8) stack_max_size =3D m8;
- stack_max_size =3D VG_PGROUNDUP(stack_max_size);
+ clstack_max_size =3D (SizeT)VG_(client_rlimit_stack).rlim_cur;
+ if (clstack_max_size < m1) clstack_max_size =3D m1;
+ if (clstack_max_size > m8) clstack_max_size =3D m8;
+ clstack_max_size =3D VG_PGROUNDUP(clstack_max_size);
=20
initial_client_SP
=3D setup_client_stack( init_sp, cl_argv, env, &info,
- &client_auxv, clstack_top, stack_max_size=
);
+ &client_auxv, clstack_top, clstack_max_si=
ze);
=20
VG_(free)(env);
}
@@ -2330,7 +2365,6 @@
// Setup client data (brk) segment. Initially a 1-page segment
// which abuts a shrinkable reservation.=20
// p: load_client() [for 'info' and hence VG_(brk_base)]
- //setup_client_dataseg();
VG_(debugLog)(1, "main", "Setup client data (brk) segment\n");
{=20
SizeT m1 =3D 1024 * 1024;
@@ -2402,7 +2436,7 @@
// If --tool and --help/--help-debug was given, now give the core+too=
l
// help message
if (need_help) {
- usage(/*--help-debug?*/2 =3D=3D need_help);
+ usage_NORETURN(/*--help-debug?*/2 =3D=3D need_help);
}
process_cmd_line_options(client_auxv, tool);
=20
@@ -2469,31 +2503,69 @@
// p: mallocfree
// p: probably: setup fds and process CLOs, so that logging works
//--------------------------------------------------------------
+ VG_(debugLog)(1, "main", "Load initial debug info\n");
{ Addr* seg_starts;
Int n_seg_starts;
- /* find out how many spaces are needed */
- VG_(am_get_segment_starts)( NULL, &n_seg_starts );
- /* allocate */
- seg_starts =3D VG_(malloc)( n_seg_starts * sizeof(Addr) );
- vg_assert(seg_starts);
- /* guard against race */
- VG_(am_get_segment_starts)( NULL, &i );
- vg_assert(n_seg_starts =3D=3D i);
- /* acquire */
- VG_(am_get_segment_starts)( seg_starts, &n_seg_starts );
+
+ seg_starts =3D get_seg_starts( &n_seg_starts );
+ vg_assert(seg_starts && n_seg_starts > 0);
+
/* show them all to the debug info reader */
for (i =3D 0; i < n_seg_starts; i++)
VG_(di_notify_mmap)( seg_starts[i] );
- /* release */
+
VG_(free)( seg_starts );
}
=20
//--------------------------------------------------------------
+ // Tell the tool about the initial client memory permissions
+ // p: aspacem
+ // p: mallocfree
+ // p: setup_client_stack
+ // p: setup_client_dataseg
+ //--------------------------------------------------------------
+ VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
+ { Addr* seg_starts;
+ Int n_seg_starts;
+ NSegment* seg;
+
+ seg_starts =3D get_seg_starts( &n_seg_starts );
+ vg_assert(seg_starts && n_seg_starts > 0);
+
+ /* show interesting ones to the tool */
+ for (i =3D 0; i < n_seg_starts; i++) {
+ seg =3D VG_(am_find_nsegment)( seg_starts[i] );
+ vg_assert(seg);
+ if (seg->kind =3D=3D SkFileC || seg->kind =3D=3D SkAnonC)
+ VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,=
=20
+ seg->hasR, seg->hasW, seg->hasX );
+ }
+
+ VG_(free)( seg_starts );
+
+ /* Also do the initial stack permissions. */
+ seg =3D VG_(am_find_nsegment)( initial_client_SP );
+ vg_assert(seg);
+ vg_assert(seg->kind =3D=3D SkAnonC);
+ vg_assert(initial_client_SP >=3D seg->start);
+ vg_assert(initial_client_SP <=3D seg->end);
+ /* Stuff below the initial SP is unaddressable. */
+ VG_TRACK( die_mem_stack, seg->start, initial_client_SP - seg->start=
);
+ }
+
+ //--------------------------------------------------------------
// Initialise the scheduler
// p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
+ // p: setup_client_stack
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Initialise scheduler\n");
- VG_(scheduler_init)();
+ { NSegment* seg =3D VG_(am_find_nsegment)( initial_client_SP );
+ vg_assert(seg);
+ vg_assert(seg->kind =3D=3D SkAnonC);
+ vg_assert(initial_client_SP >=3D seg->start);
+ vg_assert(initial_client_SP <=3D seg->end);
+ VG_(scheduler_init)( seg->end, clstack_max_size );
+ }
=20
//--------------------------------------------------------------
// Initialise the pthread model
Modified: branches/ASPACEM/coregrind/m_mallocfree.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_mallocfree.c 2005-09-19 08:08:46 UTC (re=
v 4680)
+++ branches/ASPACEM/coregrind/m_mallocfree.c 2005-09-19 17:12:04 UTC (re=
v 4681)
@@ -424,7 +424,7 @@
void ensure_mm_init ( void )
{
static Bool init_done =3D False;
- static SizeT client_redzone_szB =3D 8; // default: be paranoid
+ static SizeT client_redzone_szB =3D 16; //8; // default: be paranoi=
d
=20
if (init_done) {
// This assertion ensures that a tool cannot try to change the cli=
ent
@@ -532,9 +532,11 @@
=20
if (a->clientmem) {
// client allocation -- return 0 to client if it fails
- sb =3D (Superblock*)VG_(get_memory_from_mmap_for_client)(cszB);
- if (NULL =3D=3D sb)
+ sres =3D VG_(am_mmap_anon_float_client)
+ ( cszB, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC );
+ if (sres.isError)
return 0;
+ sb =3D (Superblock*)sres.val;
} else {
// non-client allocation -- aborts if it fails
sres =3D VG_(am_mmap_anon_float_valgrind)( cszB );
Modified: branches/ASPACEM/coregrind/m_scheduler/scheduler.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_scheduler/scheduler.c 2005-09-19 08:08:4=
6 UTC (rev 4680)
+++ branches/ASPACEM/coregrind/m_scheduler/scheduler.c 2005-09-19 17:12:0=
4 UTC (rev 4681)
@@ -535,11 +535,14 @@
caller subsequently initialises the guest state components of this
main thread, thread 1. =20
*/
-void VG_(scheduler_init) ( void )
+void VG_(scheduler_init) ( Addr clstack_end, SizeT clstack_size )
{
Int i;
ThreadId tid_main;
=20
+ vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
+ vg_assert(VG_IS_PAGE_ALIGNED(clstack_size));
+
ML_(sema_init)(&run_sema);
=20
for (i =3D 0 /* NB; not 1 */; i < VG_N_THREADS; i++) {
@@ -559,10 +562,10 @@
=20
tid_main =3D VG_(alloc_ThreadState)();
=20
- /* Initial thread's stack is the original process stack */
VG_(threads)[tid_main].client_stack_highest_word=20
- =3D VG_(clstk_end) - sizeof(=
UWord);
- VG_(threads)[tid_main].client_stack_szB =3D VG_(client_rlimit_stack)=
.rlim_cur;
+ =3D clstack_end + 1 - sizeof(UWord);
+ VG_(threads)[tid_main].client_stack_szB=20
+ =3D clstack_size;
=20
VG_(atfork_child)(sched_fork_cleanup);
}
Modified: branches/ASPACEM/coregrind/m_signals.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_signals.c 2005-09-19 08:08:46 UTC (rev 4=
680)
+++ branches/ASPACEM/coregrind/m_signals.c 2005-09-19 17:12:04 UTC (rev 4=
681)
@@ -1313,7 +1313,8 @@
=20
if (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_U=
SER)) {
VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg, "Process terminating with default action =
of signal %d (%s)%s",=20
+ VG_(message)(Vg_UserMsg,=20
+ "Process terminating with default action of signal %d=
(%s)%s",=20
sigNo, signame(sigNo), core ? ": dumping core" : "");
=20
/* Be helpful - decode some more details about this fault */
@@ -1339,11 +1340,14 @@
haveaddr =3D False;
break;
}
- VG_(am_show_nsegments)(0,"post segfault");
- {HChar buf[110];
- VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
- VG_(system)(buf);
- }
+#if 0
+ {
+ HChar buf[110];
+ VG_(am_show_nsegments)(0,"post segfault");
+ VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)())=
;
+ VG_(system)(buf);
+ }
+#endif
break;
=20
case VKI_SIGILL:
Modified: branches/ASPACEM/coregrind/m_stacktrace.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_stacktrace.c 2005-09-19 08:08:46 UTC (re=
v 4680)
+++ branches/ASPACEM/coregrind/m_stacktrace.c 2005-09-19 17:12:04 UTC (re=
v 4681)
@@ -89,7 +89,7 @@
// JRS 2002-sep-17: hack, to round up fp_max to the end of the
// current page, at least. Dunno if it helps.
// NJN 2002-sep-17: seems to -- stack traces look like 1.0.X again
- fp_max =3D (fp_max_orig + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE - 1);
+ fp_max =3D VG_PGROUNDUP(fp_max_orig);
fp_max -=3D sizeof(Addr);
=20
if (debug)
Modified: branches/ASPACEM/coregrind/pub_core_aspacemgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-19 08:08:46 U=
TC (rev 4680)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-19 17:12:04 U=
TC (rev 4681)
@@ -160,78 +160,10 @@
//--------------------------------------------------------------
// Definition of address-space segments
=20
-/* Describes segment kinds. */
-typedef
- enum {
- SkFree, // unmapped space
- SkAnonC, // anonymous mapping belonging to the client
- SkAnonV, // anonymous mapping belonging to valgrind
- SkFileC, // file mapping belonging to the client
- SkFileV, // file mapping belonging to valgrind
- SkResvn // reservation
- }
- SegKind;
+/* types SegKind, ShrinkMode and NSegment are described in
+ the tool-visible header file, not here. */
=20
-/* Describes how a reservation segment can be resized. */
-typedef
- enum {
- SmLower, // lower end can move up
- SmFixed, // cannot be shrunk
- SmUpper // upper end can move down
- }
- ShrinkMode;
=20
-/* Describes a segment. Invariants:
-
- kind =3D=3D SkFree:
- // the only meaningful fields are .start and .end
-
- kind =3D=3D SkAnon{C,V}:
- // smode=3D=3DSmFixed
- // there's no associated file:
- dev=3D=3Dino=3D=3Dfoff =3D 0, fnidx =3D=3D -1
- // segment may have permissions
-
- kind =3D=3D SkFile{C,V}:
- // smode=3D=3DSmFixed
- moveLo =3D=3D moveHi =3D=3D NotMovable, maxlen =3D=3D 0
- // there is an associated file
- // segment may have permissions
-
- kind =3D=3D SkResvn
- // the segment may be resized if required
- // there's no associated file:
- dev=3D=3Dino=3D=3Dfoff =3D 0, fnidx =3D=3D -1
- // segment has no permissions
- hasR=3D=3DhasW=3D=3DhasX=3D=3DanyTranslated =3D=3D False
-
- Also: anyTranslated=3D=3DTrue is only allowed in SkFileV and SkAnon=
V
- (viz, not allowed to make translations from non-client areas)
-*/
-typedef
- struct {
- SegKind kind;
- /* Extent (SkFree, SkAnon{C,V}, SkFile{C,V}, SkResvn) */
- Addr start; // lowest address in range
- Addr end; // highest address in range
- /* Shrinkable? (SkResvn only) */
- ShrinkMode smode;
- /* Associated file (SkFile{C,V} only) */
- UWord dev;
- UWord ino;
- ULong offset;
- Int fnIdx; // file name table index, if name is known
- /* Permissions (SkAnon{C,V}, SkFile{C,V} only) */
- Bool hasR;
- Bool hasW;
- Bool hasX;
- Bool hasT; // True --> translations have (or MAY have)
- /* Admin */ // been taken from this segment
- Bool mark;
- }
- NSegment;
-
-
//--------------------------------------------------------------
// Initialisation
=20
@@ -251,7 +183,8 @@
=20
/* Finds the segment containing 'a'. Only returns file/anon/resvn
segments. */
-extern NSegment* VG_(am_find_nsegment) ( Addr a );
+// Is in tool-visible header file.
+// extern NSegment* VG_(am_find_nsegment) ( Addr a );
=20
/* Find the next segment along from 'here', if it is a file/anon/resvn
segment. */
@@ -263,8 +196,9 @@
VKI_PROT_NONE as 'prot'. Will return False if any part of the
area does not belong to the client or does not have at least
the stated permissions. */
-extern Bool VG_(am_is_valid_for_client)
- ( Addr start, SizeT len, UInt prot );
+// Is in tool-visible header file.
+// extern Bool VG_(am_is_valid_for_client)
+// ( Addr start, SizeT len, UInt prot );
=20
/* Variant of VG_(am_is_valid_for_client) which allows free areas to
be consider part of the client's addressable space. It also
@@ -287,15 +221,8 @@
elsewhere. */
extern HChar* VG_(am_get_filename)( NSegment* );
=20
-/* Collect up the start addresses of all non-free, non-resvn segments.
- The interface is a bit strange. You have to call it twice. If
- 'starts' is NULL, the number of such segments is calculated and
- written to *nStarts. If 'starts' is non-NULL, it should point to
- an array of size *nStarts, and the segment start addresses are
- written at starts[0 .. *nStarts-1]. In the latter case, the number
- of required slots is recalculated, and the function asserts if this
- is not equal to *nStarts. */
-extern void VG_(am_get_segment_starts)( Addr* starts, Int* nStarts );
+/* VG_(am_get_segment_starts) is also part of this section, but its
+ prototype is tool-visible, hence not in this header file. */
=20
=20
//--------------------------------------------------------------
Modified: branches/ASPACEM/coregrind/pub_core_scheduler.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/pub_core_scheduler.h 2005-09-19 08:08:46 U=
TC (rev 4680)
+++ branches/ASPACEM/coregrind/pub_core_scheduler.h 2005-09-19 17:12:04 U=
TC (rev 4681)
@@ -75,7 +75,8 @@
// The scheduler.
extern VgSchedReturnCode VG_(scheduler) ( ThreadId tid );
=20
-extern void VG_(scheduler_init) ( void );
+// Initialise. Is passed the extent of the root thread's client stack.
+extern void VG_(scheduler_init) ( Addr clstack_end, SizeT clstack_size )=
;
=20
/* Stats ... */
extern void VG_(print_scheduler_stats) ( void );
Modified: branches/ASPACEM/include/pub_tool_aspacemgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/include/pub_tool_aspacemgr.h 2005-09-19 08:08:46 UTC=
(rev 4680)
+++ branches/ASPACEM/include/pub_tool_aspacemgr.h 2005-09-19 17:12:04 UTC=
(rev 4681)
@@ -31,11 +31,111 @@
#ifndef __PUB_TOOL_ASPACEMGR_H
#define __PUB_TOOL_ASPACEMGR_H
=20
+
+//--------------------------------------------------------------
+// Definition of address-space segments
+
+/* Describes segment kinds. */
+typedef
+ enum {
+ SkFree, // unmapped space
+ SkAnonC, // anonymous mapping belonging to the client
+ SkAnonV, // anonymous mapping belonging to valgrind
+ SkFileC, // file mapping belonging to the client
+ SkFileV, // file mapping belonging to valgrind
+ SkResvn // reservation
+ }
+ SegKind;
+
+/* Describes how a reservation segment can be resized. */
+typedef
+ enum {
+ SmLower, // lower end can move up
+ SmFixed, // cannot be shrunk
+ SmUpper // upper end can move down
+ }
+ ShrinkMode;
+
+/* Describes a segment. Invariants:
+
+ kind =3D=3D SkFree:
+ // the only meaningful fields are .start and .end
+
+ kind =3D=3D SkAnon{C,V}:
+ // smode=3D=3DSmFixed
+ // there's no associated file:
+ dev=3D=3Dino=3D=3Dfoff =3D 0, fnidx =3D=3D -1
+ // segment may have permissions
+
+ kind =3D=3D SkFile{C,V}:
+ // smode=3D=3DSmFixed
+ moveLo =3D=3D moveHi =3D=3D NotMovable, maxlen =3D=3D 0
+ // there is an associated file
+ // segment may have permissions
+
+ kind =3D=3D SkResvn
+ // the segment may be resized if required
+ // there's no associated file:
+ dev=3D=3Dino=3D=3Dfoff =3D 0, fnidx =3D=3D -1
+ // segment has no permissions
+ hasR=3D=3DhasW=3D=3DhasX=3D=3DanyTranslated =3D=3D False
+
+ Also: anyTranslated=3D=3DTrue is only allowed in SkFileV and SkAnon=
V
+ (viz, not allowed to make translations from non-client areas)
+*/
+typedef
+ struct {
+ SegKind kind;
+ /* Extent (SkFree, SkAnon{C,V}, SkFile{C,V}, SkResvn) */
+ Addr start; // lowest address in range
+ Addr end; // highest address in range
+ /* Shrinkable? (SkResvn only) */
+ ShrinkMode smode;
+ /* Associated file (SkFile{C,V} only) */
+ UWord dev;
+ UWord ino;
+ ULong offset;
+ Int fnIdx; // file name table index, if name is known
+ /* Permissions (SkAnon{C,V}, SkFile{C,V} only) */
+ Bool hasR;
+ Bool hasW;
+ Bool hasX;
+ Bool hasT; // True --> translations have (or MAY have)
+ /* Admin */ // been taken from this segment
+ Bool mark;
+ }
+ NSegment;
+
+
+/* Collect up the start addresses of all non-free, non-resvn segments.
+ The interface is a bit strange in order to avoid potential
+ segment-creation races caused by dynamic allocation of the result
+ buffer *starts.
+
+ The function first computes how many entries in the result
+ buffer *starts will be needed. If this number <=3D nStarts,
+ they are placed in starts[0..], and the number is returned.
+ If nStarts is not large enough, nothing is written to
+ starts[0..], and the negation of the size is returned.
+
+ Correct use of this function may mean calling it multiple times in
+ order to establish a suitably-sized buffer. */
+extern Int VG_(am_get_segment_starts)( Addr* starts, Int nStarts );
+
+
+// See pub_core_aspacemgr.h for description.
+extern NSegment* VG_(am_find_nsegment) ( Addr a );=20
+
+// See pub_core_aspacemgr.h for description.
+extern Bool VG_(am_is_valid_for_client) ( Addr start, SizeT len,=20
+ UInt prot );
+
extern Bool VG_(is_client_addr) (Addr a);
=20
extern Bool VG_(is_shadow_addr) (Addr a);
=20
-extern void *VG_(shadow_alloc)(UInt size);
+/* Really just a wrapper around VG_(am_mmap_anon_float_valgrind). */
+extern void* VG_(am_shadow_alloc)(SizeT size);
=20
extern Bool VG_(is_addressable)(Addr p, SizeT sz, UInt prot);
=20
Modified: branches/ASPACEM/memcheck/mac_leakcheck.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/memcheck/mac_leakcheck.c 2005-09-19 08:08:46 UTC (re=
v 4680)
+++ branches/ASPACEM/memcheck/mac_leakcheck.c 2005-09-19 17:12:04 UTC (re=
v 4681)
@@ -72,6 +72,41 @@
__builtin_longjmp(memscan_jmpbuf, 1);
}
=20
+
+/* TODO: GIVE THIS A PROPER HOME
+ TODO: MERGE THIS WITH DUPLICATE IN m_main.c
+ Extract from aspacem a vector of the current segment start
+ addresses. The vector is dynamically allocated and should be freed
+ by the caller when done. REQUIRES m_mallocfree to be running.
+ Writes the number of addresses required into *n_acquired. */
+
+static Addr* get_seg_starts ( /*OUT*/Int* n_acquired )
+{
+ Addr* starts;
+ Int n_starts, r;
+
+ n_starts =3D 1;
+ while (True) {
+ starts =3D VG_(malloc)( n_starts * sizeof(Addr) );
+ if (starts =3D=3D NULL)
+ break;
+ r =3D VG_(am_get_segment_starts)( starts, n_starts );
+ if (r >=3D 0)
+ break;
+ VG_(free)(starts);
+ n_starts *=3D 2;
+ }
+
+ if (starts =3D=3D NULL) {
+ *n_acquired =3D 0;
+ return NULL;
+ }
+
+ *n_acquired =3D r;
+ return starts;
+}
+
+
/*------------------------------------------------------------*/
/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
/*------------------------------------------------------------*/
@@ -293,7 +328,8 @@
{
Int sh_no;
=20
- if (!VG_(is_client_addr)(ptr)) /* quick filter */
+ /* quick filter */
+ if (!VG_(am_is_valid_for_client)(ptr, 1, VKI_PROT_NONE))
return;
=20
sh_no =3D find_shadow_for(ptr, lc_shadows, lc_n_shadows);
@@ -393,8 +429,7 @@
=20
lc_scanned +=3D end-ptr;
=20
- if (!VG_(is_client_addr)(ptr) ||
- !VG_(is_addressable)(ptr, sizeof(Addr), VKI_PROT_READ))
+ if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ))
ptr =3D VG_PGROUNDUP(ptr+1); /* first page bad */
=20
while (ptr < end) {
@@ -408,8 +443,7 @@
=20
/* Look to see if this page seems reasonble */
if ((ptr % VKI_PAGE_SIZE) =3D=3D 0) {
- if (!VG_(is_client_addr)(ptr) ||
- !VG_(is_addressable)(ptr, sizeof(Addr), VKI_PROT_READ))
+ if (!VG_(am_is_valid_for_client)(ptr, sizeof(Addr), VKI_PROT_READ))
ptr +=3D VKI_PAGE_SIZE; /* bad page - skip it */
}
=20
@@ -692,8 +726,24 @@
=20
lc_scanned =3D 0;
=20
- /* Do the scan of memory, pushing any pointers onto the mark stack */
- VG_(find_root_memory)(lc_scan_memory);
+ /* Do the scan of memory, pushing any pointers onto the mark stack.
+ Here, we iterate over the segment array, handing any RW client
+ sections to lc_scan_memory. */
+ { NSegment* seg;
+ Addr* seg_starts;
+ Int n_seg_starts;
+ seg_starts =3D get_seg_starts( &n_seg_starts );
+ tl_assert(seg_starts && n_seg_starts > 0);
+ for (i =3D 0; i < n_seg_starts; i++) {
+ seg =3D VG_(am_find_nsegment)( seg_starts[i] );
+ tl_assert(seg);
+ if (seg->kind !=3D SkFileC && seg->kind !=3D SkAnonC)=20
+ continue;
+ if (!(seg->hasR && seg->hasW))
+ continue;
+ lc_scan_memory(seg->start, seg->end+1 - seg->start);
+ }
+ }
=20
/* Push registers onto mark stack */
VG_(apply_to_GP_regs)(lc_markstack_push);
Modified: branches/ASPACEM/memcheck/mc_main.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/memcheck/mc_main.c 2005-09-19 08:08:46 UTC (rev 4680=
)
+++ branches/ASPACEM/memcheck/mc_main.c 2005-09-19 17:12:04 UTC (rev 4681=
)
@@ -190,7 +190,7 @@
|| dist_sm =3D=3D &sm_distinguished[1]
|| dist_sm =3D=3D &sm_distinguished[2]);
=20
- new_sm =3D VG_(shadow_alloc)(sizeof(SecMap));
+ new_sm =3D VG_(am_shadow_alloc)(sizeof(SecMap));
VG_(memcpy)(new_sm, dist_sm, sizeof(SecMap));
n_secmaps_issued++;
return new_sm;
|