|
From: <sv...@va...> - 2005-09-24 11:57:24
|
Author: sewardj
Date: 2005-09-24 12:57:15 +0100 (Sat, 24 Sep 2005)
New Revision: 4743
Log:
* Implement code discarding for sys_mremap
* Fix yet another bug in sys_mremap
* Implement code discarding for sys_brk, when dataseg shrinks
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.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-24 02:53:1=
5 UTC (rev 4742)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-24 11:57:1=
5 UTC (rev 4743)
@@ -1203,7 +1203,7 @@
translations made from it. This is used to determine when to
discard code, so if in doubt return True. */
=20
-static Bool anyTs_in_range ( Addr start, SizeT len )
+static Bool any_Ts_in_range ( Addr start, SizeT len )
{
Int iLo, iHi, i;
aspacem_assert(len > 0);
@@ -1749,7 +1749,7 @@
aspacem_assert(VG_IS_PAGE_ALIGNED(len));
=20
/* Discard is needed if any of the just-trashed range had T. */
- needDiscard =3D anyTs_in_range( a, len );
+ needDiscard =3D any_Ts_in_range( a, len );
=20
init_nsegment( &seg );
seg.kind =3D (flags & VKI_MAP_ANONYMOUS) ? SkAnonC : SkFileC;
@@ -1799,7 +1799,7 @@
newX =3D toBool(prot & VKI_PROT_EXEC);
=20
/* Discard is needed if we're dumping X permission */
- needDiscard =3D anyTs_in_range( start, len ) && !newX;
+ needDiscard =3D any_Ts_in_range( start, len ) && !newX;
=20
split_nsegments_lo_and_hi( start, start+len-1, &iLo, &iHi );
=20
@@ -1845,7 +1845,7 @@
if (len =3D=3D 0)
return False;
=20
- needDiscard =3D anyTs_in_range( start, len );
+ needDiscard =3D any_Ts_in_range( start, len );
=20
init_nsegment( &seg );
seg.kind =3D SkFree;
@@ -2191,15 +2191,19 @@
/* --- --- munmap helper --- --- */
=20
static=20
-SysRes am_munmap_both_wrk ( Addr start, SizeT len, Bool forClient )
+SysRes am_munmap_both_wrk ( /*OUT*/Bool* need_discard,
+ Addr start, SizeT len, Bool forClient )
{
+ Bool d;
SysRes sres;
=20
if (!VG_IS_PAGE_ALIGNED(start))
goto eINVAL;
=20
- if (len =3D=3D 0)
+ if (len =3D=3D 0) {
+ *need_discard =3D False;
return VG_(mk_SysRes_Success)( 0 );
+ }
=20
if (start + len < len)
goto eINVAL;
@@ -2217,12 +2221,15 @@
goto eINVAL;
}
=20
+ d =3D any_Ts_in_range( start, len );
+
sres =3D do_munmap_NO_NOTIFY( start, len );
if (sres.isError)
return sres;
=20
VG_(am_notify_munmap)( start, len );
AM_SANITY_CHECK;
+ *need_discard =3D d;
return sres;
=20
eINVAL:
@@ -2230,12 +2237,15 @@
}
=20
/* Unmap the given address range and update the segment array
- accordingly. This fails if the range isn't valid for the
- client. */
+ accordingly. This fails if the range isn't valid for the client.
+ If *need_discard is True after a successful return, the caller
+ should immediately discard translations from the specified address
+ range. */
=20
-SysRes VG_(am_munmap_client)( Addr start, SizeT len )
+SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
+ Addr start, SizeT len )
{
- return am_munmap_both_wrk( start, len, True/*client*/ );
+ return am_munmap_both_wrk( need_discard, start, len, True/*client*/ )=
;
}
=20
/* Unmap the given address range and update the segment array
@@ -2243,7 +2253,14 @@
=20
SysRes VG_(am_munmap_valgrind)( Addr start, SizeT len )
{
- return am_munmap_both_wrk( start, len, False/*valgrind*/ );
+ Bool need_discard;
+ SysRes r =3D am_munmap_both_wrk( &need_discard,=20
+ start, len, False/*valgrind*/ );
+ /* If this assertion fails, it means we allowed translations to be
+ made from a V-owned section. Which shouldn't happen. */
+ if (!r.isError)
+ aspacem_assert(!need_discard);
+ return r;
}
=20
/* Let (start,len) denote an area within a single Valgrind-owned
@@ -2461,9 +2478,12 @@
the mapping forwards only by DELTA bytes, and trashes whatever was
in the new area. Fails if SEG is not a single client mapping or if
the new area is not accessible to the client. Fails if DELTA is
- not page aligned. *seg is invalid after a successful return. */
+ not page aligned. *seg is invalid after a successful return. If
+ *need_discard is True after a successful return, the caller should
+ immediately discard translations from the new area. */
=20
-Bool VG_(am_extend_map_client)( NSegment* seg, SizeT delta )
+Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
+ NSegment* seg, SizeT delta )
{
Addr xStart;
SysRes sres;
@@ -2493,6 +2513,8 @@
return False;
}
=20
+ *need_discard =3D any_Ts_in_range( seg_copy.end+1, delta );
+
seg_copy.end +=3D delta;
add_segment( &seg_copy );
=20
@@ -2506,9 +2528,12 @@
wraparound is implied, if the old address range does not fall
entirely within a single segment, if the new address range overlaps
with the old one, or if the old address range is not a valid client
- mapping. */
+ mapping. If *need_discard is True after a successful return, the
+ caller should immediately discard translations from both specified
+ address ranges. */
=20
-Bool VG_(am_relocate_nooverlap_client)( Addr old_addr, SizeT old_len,
+Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
+ Addr old_addr, SizeT old_len,
Addr new_addr, SizeT new_len )
{
Int iLo, iHi;
@@ -2547,6 +2572,9 @@
return False;
}
=20
+ *need_discard =3D any_Ts_in_range( old_addr, old_len )
+ || any_Ts_in_range( new_addr, new_len );
+
oldseg =3D nsegments[iLo];
=20
/* Create a free hole in the old location. */
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-24 02:=
53:15 UTC (rev 4742)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c 2005-09-24 11:=
57:15 UTC (rev 4743)
@@ -175,7 +175,7 @@
{
# define MIN_SIZET(_aa,_bb) (_aa) < (_bb) ? (_aa) : (_bb)
=20
- Bool ok;
+ Bool ok, d;
NSegment* old_seg;
Addr advised;
Bool f_fixed =3D toBool(flags & VKI_MREMAP_FIXED);
@@ -294,7 +294,7 @@
if (!ok || advised !=3D new_addr)
goto eNOMEM;
ok =3D VG_(am_relocate_nooverlap_client)
- ( old_addr, old_len, new_addr, new_len );
+ ( &d, old_addr, old_len, new_addr, new_len );
if (ok) {
VG_TRACK( copy_mem_remap, old_addr, new_addr,=20
MIN_SIZET(old_len,new_len) );
@@ -302,6 +302,10 @@
VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len,
old_seg->hasR, old_seg->hasW, old_seg->hasX );
VG_TRACK(die_mem_munmap, old_addr, old_len);
+ if (d) {
+ VG_(discard_translations)( old_addr, old_len );
+ VG_(discard_translations)( new_addr, new_len );
+ }
return VG_(mk_SysRes_Success)( new_addr );
}
goto eNOMEM;
@@ -323,11 +327,13 @@
non-fixed, which is not what we want */
advised =3D VG_(am_get_advisory_client_simple)( needA, needL, &ok );
if (ok && advised =3D=3D needA) {
- ok =3D VG_(am_extend_map_client)( old_seg, needL );
+ ok =3D VG_(am_extend_map_client)( &d, old_seg, needL );
if (ok) {
VG_TRACK( new_mem_mmap, needA, needL,=20
old_seg->hasR,=20
old_seg->hasW, old_seg->hasX );
+ if (d)=20
+ VG_(discard_translations)( needA, needL );
return VG_(mk_SysRes_Success)( old_addr );
}
}
@@ -339,14 +345,18 @@
vg_assert(advised+new_len-1 < old_addr=20
|| advised > old_addr+old_len-1);
ok =3D VG_(am_relocate_nooverlap_client)
- ( old_addr, old_len, advised, new_len );
+ ( &d, old_addr, old_len, advised, new_len );
if (ok) {
- VG_TRACK( copy_mem_remap, old_addr, new_addr,=20
+ VG_TRACK( copy_mem_remap, old_addr, advised,=20
MIN_SIZET(old_len,new_len) );
if (new_len > old_len)
- VG_TRACK( new_mem_mmap, new_addr+old_len, new_len-old_len,
+ VG_TRACK( new_mem_mmap, advised+old_len, new_len-old_len,
old_seg->hasR, old_seg->hasW, old_seg->hasX );
VG_TRACK(die_mem_munmap, old_addr, old_len);
+ if (d) {
+ VG_(discard_translations)( old_addr, old_len );
+ VG_(discard_translations)( advised, new_len );
+ }
return VG_(mk_SysRes_Success)( advised );
}
}
@@ -365,21 +375,25 @@
advised =3D VG_(am_get_advisory_client_simple)( needA, needL, &ok );
if (!ok || advised !=3D needA)
goto eNOMEM;
- ok =3D VG_(am_extend_map_client)( old_seg, needL );
+ ok =3D VG_(am_extend_map_client)( &d, old_seg, needL );
if (!ok)
goto eNOMEM;
VG_TRACK( new_mem_mmap, needA, needL,=20
old_seg->hasR, old_seg->hasW, old_seg->hasX )=
;
+ if (d)
+ VG_(discard_translations)( needA, needL );
return VG_(mk_SysRes_Success)( old_addr );
}
/*NOTREACHED*/ vg_assert(0);
=20
shrink_in_place:
{
- SysRes sres =3D VG_(am_munmap_client)( old_addr+new_len, old_len-new_=
len );
+ SysRes sres =3D VG_(am_munmap_client)( &d, old_addr+new_len, old_len-=
new_len );
if (sres.isError)
return sres;
VG_TRACK( die_mem_munmap, old_addr+new_len, old_len-new_len );
+ if (d)
+ VG_(discard_translations)( old_addr+new_len, old_len-new_len );
return VG_(mk_SysRes_Success)( old_addr );
}
/*NOTREACHED*/ vg_assert(0);
@@ -928,6 +942,7 @@
if (newbrk >=3D VG_(brk_base) && newbrk < VG_(brk_limit)) {
/* shrinking the data segment. Be lazy and don't munmap the
excess area. */
+ VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk );
VG_(brk_limit) =3D newbrk;
return newbrk;
}
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-24 02:53:15 U=
TC (rev 4742)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-24 11:57:15 U=
TC (rev 4743)
@@ -226,9 +226,12 @@
( SizeT length, UInt prot, Int fd, SizeT offset );
=20
/* Unmap the given address range and update the segment array
- accordingly. This fails if the range isn't valid for the
- client. */
-extern SysRes VG_(am_munmap_client)( Addr start, SizeT length );
+ accordingly. This fails if the range isn't valid for the client.
+ If *need_discard is True after a successful return, the caller
+ should immediately discard translations from the specified address
+ range. */
+extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
+ Addr start, SizeT length );
=20
/* Unmap the given address range and update the segment array
accordingly. This fails if the range isn't valid for valgrind. */
@@ -270,16 +273,22 @@
the mapping forwards only by DELTA bytes, and trashes whatever was
in the new area. Fails if SEG is not a single client mapping or if
the new area is not accessible to the client. Fails if DELTA is
- not page aligned. *seg is invalid after a successful return. */
-extern Bool VG_(am_extend_map_client)( NSegment* seg, SizeT delta );
+ not page aligned. *seg is invalid after a successful return. If
+ *need_discard is True after a successful return, the caller should
+ immediately discard translations from the new area. */
+extern Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
+ NSegment* seg, SizeT delta );
=20
/* Remap the old address range to the new address range. Fails if any
parameter is not page aligned, if the either size is zero, if any
wraparound is implied, if the old address range does not fall
entirely within a single segment, if the new address range overlaps
with the old one, or if the old address range is not a valid client
- mapping. */
-extern Bool VG_(am_relocate_nooverlap_client)( Addr old_addr, SizeT old_=
len,
+ mapping. If *need_discard is True after a successful return, the
+ caller should immediately discard translations from both specified
+ address ranges. */
+extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard=
,
+ Addr old_addr, SizeT old_=
len,
Addr new_addr, SizeT new_=
len );
=20
//--------------------------------------------------------------
|