|
From: <sv...@va...> - 2005-09-24 02:53:20
|
Author: sewardj
Date: 2005-09-24 03:53:15 +0100 (Sat, 24 Sep 2005)
New Revision: 4742
Log:
Discard translations after munmap/mprotect/mmap. This makes Qt
designer and Gimp work. mremap is not done yet.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_main.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-linux.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-main.c
branches/ASPACEM/coregrind/m_translate.c
branches/ASPACEM/coregrind/pub_core_aspacemgr.h
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-23 21:29:5=
1 UTC (rev 4741)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-24 02:53:1=
5 UTC (rev 4742)
@@ -1199,6 +1199,25 @@
}
=20
=20
+/* Returns True if any part of the address range is marked as having
+ translations made from it. This is used to determine when to
+ discard code, so if in doubt return True. */
+
+static Bool anyTs_in_range ( Addr start, SizeT len )
+{
+ Int iLo, iHi, i;
+ aspacem_assert(len > 0);
+ aspacem_assert(start + len > start);
+ iLo =3D find_nsegment_idx(start);
+ iHi =3D find_nsegment_idx(start + len - 1);
+ for (i =3D iLo; i <=3D iHi; i++) {
+ if (nsegments[i].hasT)
+ return True;
+ }
+ return False;
+}
+
+
/*-----------------------------------------------------------------*/
/*--- ---*/
/*--- Modifying the segment array, and constructing segments. ---*/
@@ -1712,19 +1731,26 @@
=20
=20
/* Notifies aspacem that the client completed an mmap successfully.
- The segment array is updated accordingly. */
+ The segment array is updated accordingly. If the returned Bool is
+ True, the caller should immediately discard translations from the
+ specified address range. */
=20
-void=20
+Bool
VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags,
Int fd, SizeT offset )
{
HChar buf[VKI_PATH_MAX];
UInt dev, ino;
NSegment seg;
+ Bool needDiscard;
=20
aspacem_assert(len > 0);
aspacem_assert(VG_IS_PAGE_ALIGNED(a));
aspacem_assert(VG_IS_PAGE_ALIGNED(len));
+
+ /* Discard is needed if any of the just-trashed range had T. */
+ needDiscard =3D anyTs_in_range( a, len );
+
init_nsegment( &seg );
seg.kind =3D (flags & VKI_MAP_ANONYMOUS) ? SkAnonC : SkFileC;
seg.start =3D a;
@@ -1744,6 +1770,7 @@
}
add_segment( &seg );
AM_SANITY_CHECK;
+ return needDiscard;
}
=20
/* Notifies aspacem that an mprotect was completed successfully. The
@@ -1752,28 +1779,33 @@
stupid mprotects, for example the client doing mprotect of
non-client areas. Such requests should be intercepted earlier, by
the syscall wrapper for mprotect. This function merely records
- whatever it is told. */
+ whatever it is told. If the returned Bool is True, the caller
+ should immediately discard translations from the specified address
+ range. */
=20
-void VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot )
+Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot )
{
Int i, iLo, iHi;
- Bool newR, newW, newX;
+ Bool newR, newW, newX, needDiscard;
=20
aspacem_assert(VG_IS_PAGE_ALIGNED(start));
aspacem_assert(VG_IS_PAGE_ALIGNED(len));
=20
if (len =3D=3D 0)
- return;
+ return False;
=20
+ newR =3D toBool(prot & VKI_PROT_READ);
+ newW =3D toBool(prot & VKI_PROT_WRITE);
+ newX =3D toBool(prot & VKI_PROT_EXEC);
+
+ /* Discard is needed if we're dumping X permission */
+ needDiscard =3D anyTs_in_range( start, len ) && !newX;
+
split_nsegments_lo_and_hi( start, start+len-1, &iLo, &iHi );
=20
iLo =3D find_nsegment_idx(start);
iHi =3D find_nsegment_idx(start + len - 1);
=20
- newR =3D toBool(prot & VKI_PROT_READ);
- newW =3D toBool(prot & VKI_PROT_WRITE);
- newX =3D toBool(prot & VKI_PROT_EXEC);
-
for (i =3D iLo; i <=3D iHi; i++) {
/* Apply the permissions to all relevant segments. */
switch (nsegments[i].kind) {
@@ -1792,24 +1824,29 @@
segments mergeable. Therefore have to re-preen them. */
(void)preen_nsegments();
AM_SANITY_CHECK;
+ return needDiscard;
}
=20
=20
/* Notifies aspacem that an munmap completed successfully. The
segment array is updated accordingly. As with
VG_(am_notify_munmap), we merely record the given info, and don't
- check it for sensibleness. */
+ check it for sensibleness. If the returned Bool is True, the
+ caller should immediately discard translations from the specified
+ address range. */
=20
-void VG_(am_notify_munmap)( Addr start, SizeT len )
+Bool VG_(am_notify_munmap)( Addr start, SizeT len )
{
NSegment seg;
-
+ Bool needDiscard;
aspacem_assert(VG_IS_PAGE_ALIGNED(start));
aspacem_assert(VG_IS_PAGE_ALIGNED(len));
=20
if (len =3D=3D 0)
- return;
+ return False;
=20
+ needDiscard =3D anyTs_in_range( start, len );
+
init_nsegment( &seg );
seg.kind =3D SkFree;
seg.start =3D start;
@@ -1819,6 +1856,7 @@
/* Unmapping could create two adjacent free segments, so a preen is
needed. add_segment() will do that, so no need to here. */
AM_SANITY_CHECK;
+ return needDiscard;
}
=20
=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-23 21:29:51 UTC (rev 4741=
)
+++ branches/ASPACEM/coregrind/m_main.c 2005-09-24 02:53:15 UTC (rev 4742=
)
@@ -1577,7 +1577,10 @@
if (log_to !=3D VgLogTo_Fd)
VG_(message)(Vg_DebugMsg, "");
VG_(message)(Vg_DebugMsg, "Valgrind library directory: %s", VG_(li=
bdir));
+
VG_(message)(Vg_DebugMsg, "Command line");
+ if (VG_(args_the_exename))
+ VG_(message)(Vg_DebugMsg, " %s", VG_(args_the_exename));
for (i =3D 0; i < VG_(args_for_client).used; i++)
VG_(message)(Vg_DebugMsg, " %s", VG_(args_for_client).strs[i]=
);
=20
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.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_syswrap/syswrap-generic.c 2005-09-23 21:=
29:51 UTC (rev 4741)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c 2005-09-24 02:=
53:15 UTC (rev 4742)
@@ -32,6 +32,7 @@
#include "pub_core_threadstate.h"
#include "pub_core_debuginfo.h" // VG_(di_notify_*)
#include "pub_core_aspacemgr.h"
+#include "pub_core_transtab.h" // VG_(discard_translations)
#include "pub_core_clientstate.h" // VG_(brk_base), VG_(brk_limit)
#include "pub_core_debuglog.h"
#include "pub_core_errormgr.h"
@@ -145,20 +146,23 @@
ML_(notify_aspacem_and_tool_of_mmap) ( Addr a, SizeT len, UInt prot,=20
UInt flags, Int fd, ULong offset =
)
{
- Bool rr, ww, xx;
+ Bool rr, ww, xx, d;
=20
/* 'a' is the return value from a real kernel mmap, hence: */
vg_assert(VG_IS_PAGE_ALIGNED(a));
/* whereas len is whatever the syscall supplied. So: */
len =3D VG_PGROUNDUP(len);
=20
- VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
+ d =3D VG_(am_notify_client_mmap)( a, len, prot, flags, fd, offset );
=20
rr =3D toBool(prot & VKI_PROT_READ);
ww =3D toBool(prot & VKI_PROT_WRITE);
xx =3D toBool(prot & VKI_PROT_EXEC);
=20
VG_TRACK( new_mem_mmap, a, len, rr, ww, xx );
+
+ if (d)
+ VG_(discard_translations)( (Addr64)a, (ULong)len );
}
=20
/* Expand (or shrink) an existing mapping, potentially moving it at
@@ -1632,6 +1636,7 @@
UInt segmentSize =3D get_shm_size ( arg0 );
if ( segmentSize > 0 ) {
UInt prot =3D VKI_PROT_READ|VKI_PROT_WRITE;
+ Bool d;
=20
if (!(arg2 & 010000)) /* =3D SHM_RDONLY */
prot &=3D ~VKI_PROT_WRITE;
@@ -1645,12 +1650,15 @@
cope with the discrepancy, aspacem's sync checker omits the
dev/ino correspondence check in cases where V does not know
the dev/ino. */
- VG_(am_notify_client_mmap)( res, VG_PGROUNDUP(segmentSize),=20
- prot, VKI_MAP_ANONYMOUS, 0,0);
+ d =3D VG_(am_notify_client_mmap)( res, VG_PGROUNDUP(segmentSize),=20
+ prot, VKI_MAP_ANONYMOUS, 0,0);
=20
/* we don't distinguish whether it's read-only or
* read-write -- it doesn't matter really. */
VG_TRACK( new_mem_mmap, res, segmentSize, True, True, False );
+ if (d)
+ VG_(discard_translations)( (Addr64)res,=20
+ (ULong)VG_PGROUNDUP(segmentSize) );
}
}
=20
@@ -1666,13 +1674,16 @@
void
ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
{
- NSegment *s =3D VG_(am_find_nsegment)(arg0);
+ NSegment* s =3D VG_(am_find_nsegment)(arg0);
=20
if (s !=3D NULL /* && (s->flags & SF_SHM) */
/* && Implied by defn of am_find_nsegment:
VG_(seg_contains)(s, arg0, 1) */) {
- VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
+ Bool d =3D VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
+ if (d)
+ VG_(discard_translations)( (Addr64)(s->start),
+ (ULong)(s->end+1 - s->start) );
}
}
/* ------ */
@@ -4835,11 +4846,14 @@
Bool rr =3D toBool(prot & VKI_PROT_READ);
Bool ww =3D toBool(prot & VKI_PROT_WRITE);
Bool xx =3D toBool(prot & VKI_PROT_EXEC);
+ Bool d;
=20
page_align_addr_and_len(&a, &len);
- VG_(am_notify_mprotect)(a, len, prot);
+ d =3D VG_(am_notify_mprotect)(a, len, prot);
VG_TRACK( change_mem_mprotect, a, len, rr, ww, xx );
VG_(di_notify_mprotect)( a, len, prot );
+ if (d)
+ VG_(discard_translations)( (Addr64)a, (ULong)len );
}
=20
PRE(sys_munmap)
@@ -4856,11 +4870,14 @@
{
Addr a =3D ARG1;
SizeT len =3D ARG2;
+ Bool d;
=20
page_align_addr_and_len(&a, &len);
- VG_(am_notify_munmap)(a, len);
+ d =3D VG_(am_notify_munmap)(a, len);
VG_TRACK( die_mem_munmap, a, len );
VG_(di_notify_munmap)( a, len );
+ if (d)
+ VG_(discard_translations)( (Addr64)a, (ULong)len );
}
=20
PRE(sys_mincore)
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-linux.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_syswrap/syswrap-linux.c 2005-09-23 21:29=
:51 UTC (rev 4741)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-linux.c 2005-09-24 02:53=
:15 UTC (rev 4742)
@@ -31,6 +31,7 @@
#include "pub_core_basics.h"
#include "pub_core_threadstate.h"
#include "pub_core_aspacemgr.h"
+#include "pub_core_transtab.h" // VG_(discard_translations)
#include "pub_core_debuglog.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
@@ -722,8 +723,10 @@
SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
=20
if (SUCCESS && RES =3D=3D 0) {=20
- VG_(am_notify_munmap)( ARG1, size );
+ Bool d =3D VG_(am_notify_munmap)( ARG1, size );
VG_TRACK( die_mem_munmap, ARG1, size );
+ if (d)
+ VG_(discard_translations)( (Addr64)ARG1, (ULong)size );
} =20
} =20
=20
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-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_syswrap/syswrap-main.c 2005-09-23 21:29:=
51 UTC (rev 4741)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-main.c 2005-09-24 02:53:=
15 UTC (rev 4742)
@@ -180,18 +180,27 @@
should be notified BEFORE the tool. Hence the following is
correct:
=20
- VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
+ Bool d =3D VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
+ if (d)
+ VG_(discard_translations)(s->start, s->end+1 - s->start);
=20
whilst this is wrong:
=20
VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
- VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
+ Bool d =3D VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
+ if (d)
+ VG_(discard_translations)(s->start, s->end+1 - s->start);
=20
The reason is that the tool may itself ask aspacem for more shadow
memory as a result of the VG_TRACK call. In such a situation it is
critical that aspacem's segment array is up to date -- hence the
need to notify aspacem first.
+
+ -----------
+
+ Also .. take care to call VG_(discard_translations) whenever
+ memory with execute permissions is unmapped.
*/
=20
=20
Modified: branches/ASPACEM/coregrind/m_translate.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_translate.c 2005-09-23 21:29:51 UTC (rev=
4741)
+++ branches/ASPACEM/coregrind/m_translate.c 2005-09-24 02:53:15 UTC (rev=
4742)
@@ -441,7 +441,7 @@
ULong bbs_done )
{
Addr64 redir, orig_addr0 =3D orig_addr;
- Int tmpbuf_used, verbosity;
+ Int tmpbuf_used, verbosity, i;
Bool notrace_until_done, do_self_check, allowR, seg_ok;
UInt notrace_until_limit =3D 0;
NSegment* seg;
@@ -545,7 +545,6 @@
&& (seg->hasX || (seg->hasR && allowR));
=20
if (!seg_ok) {
-
/* U R busted, sonny. Place your hands on your head and step
away from the orig_addr. */
/* Code address is bad - deliver a signal instead */
@@ -559,15 +558,8 @@
VG_(synth_fault_mapping)(tid, orig_addr);
}
return False;
-
- } else {
-
- /* Ok to execute here. Mark that we have taken a translation
- from this segment. */
- seg->hasT =3D True; /* contains cached code */
}
=20
-
/* Do we want a self-checking translation? */
do_self_check =3D False;
switch (VG_(clo_smc_check)) {
@@ -630,6 +622,14 @@
=20
VGP_POPCC(VgpVexTime);
=20
+ /* Tell aspacem of all segments that have had translations taken
+ from them. */
+ for (i =3D 0; i < vge.n_used; i++) {
+ seg =3D VG_(am_find_nsegment)( vge.base[i] );
+ if (seg->kind =3D=3D SkFileC || seg->kind =3D=3D SkAnonC)
+ seg->hasT =3D True; /* has cached code */
+ }
+
/* Copy data at trans_addr into the translation cache. */
vg_assert(tmpbuf_used > 0 && tmpbuf_used < 65536);
=20
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-23 21:29:51 U=
TC (rev 4741)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-24 02:53:15 U=
TC (rev 4742)
@@ -157,8 +157,10 @@
( Addr start, SizeT len, /*OUT*/Bool* ok );
=20
/* Notifies aspacem that the client completed an mmap successfully.
- The segment array is updated accordingly. */
-extern void VG_(am_notify_client_mmap)
+ The segment array is updated accordingly. If the returned Bool is
+ True, the caller should immediately discard translations from the
+ specified address range. */
+extern Bool VG_(am_notify_client_mmap)
( Addr a, SizeT len, UInt prot, UInt flags, Int fd, SizeT offset );
=20
/* Notifies aspacem that an mprotect was completed successfully. The
@@ -167,14 +169,18 @@
stupid mprotects, for example the client doing mprotect of
non-client areas. Such requests should be intercepted earlier, by
the syscall wrapper for mprotect. This function merely records
- whatever it is told. */
-extern void VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
+ whatever it is told. If the returned Bool is True, the caller
+ should immediately discard translations from the specified address
+ range. */
+extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
=20
/* Notifies aspacem that an munmap completed successfully. The
segment array is updated accordingly. As with
VG_(am_notify_munmap), we merely record the given info, and don't
- check it for sensibleness. */
-extern void VG_(am_notify_munmap)( Addr start, SizeT len );
+ check it for sensibleness. If the returned Bool is True, the
+ caller should immediately discard translations from the specified
+ address range. */
+extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
=20
=20
/* Hand a raw mmap to the kernel, without aspacem updating the segment
|