|
From: <sv...@va...> - 2005-09-13 11:52:12
|
Author: sewardj
Date: 2005-09-13 12:52:09 +0100 (Tue, 13 Sep 2005)
New Revision: 4637
Log:
Non-functional change: rename, reformat, comment, the new spacemgr
code so it no longer looks such a complete mess.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_main.c
branches/ASPACEM/coregrind/m_mallocfree.c
branches/ASPACEM/coregrind/m_signals.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-linux.c
branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.c
branches/ASPACEM/coregrind/m_translate.c
branches/ASPACEM/coregrind/m_transtab.c
branches/ASPACEM/coregrind/m_ume.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-13 11:13:4=
3 UTC (rev 4636)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-13 11:52:0=
9 UTC (rev 4637)
@@ -1346,6 +1346,94 @@
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
=20
+
+/* Note: many of the exported functions implemented below are
+ described more fully in comments in pub_core_aspacemgr.h.
+*/
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- The Address Space Manager's state. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Array [0 .. nsegments_used-1] of all mappings. */
+/* Sorted by .addr field. */
+/* I: len may not be zero. */
+/* I: overlapping segments are not allowed. */
+/* I: the segments cover the entire address space precisely. */
+/* Each segment can optionally hold an index into the filename table. */
+
+static NSegment nsegments[VG_N_SEGMENTS];
+static Int nsegments_used =3D 0;
+
+#define Addr_MIN ((Addr)0)
+#define Addr_MAX ((Addr)(-1ULL))
+
+/* Limits etc */
+
+// The smallest address that aspacem will try to allocate
+static Addr aspacem_minAddr =3D 0;
+
+// The largest address that aspacem will try to allocate
+static Addr aspacem_maxAddr =3D 0;
+
+// Where aspacem will start looking for client space
+static Addr aspacem_cStart =3D 0;
+
+// Where aspacem will start looking for Valgrind space
+static Addr aspacem_vStart =3D 0;
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Stuff to make aspacem almost completely independent of ---*/
+/*--- the rest of Valgrind. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+//--------------------------------------------------------------
+// Simple assert and assert-like fns, which avoid dependence on
+// m_libcassert, and hence on the entire debug-info reader swamp
+
+static void aspacem_barf ( HChar* what )
+{
+ VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: %s\n", what);
+ VG_(debugLog)(0, "aspacem", "Exiting now.\n");
+ VG_(exit)(1);
+}
+
+static void aspacem_barf_toolow ( HChar* what )
+{
+ VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: %s is too low.\n", what)=
;
+ VG_(debugLog)(0, "aspacem", " Increase it and rebuild. "
+ "Exiting now.\n");
+ VG_(exit)(1);
+}
+
+static void aspacem_assert_fail( const HChar* expr,
+ const Char* file,
+ Int line,=20
+ const Char* fn )
+{
+ VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: aspacem assertion failed=
:\n");
+ VG_(debugLog)(0, "aspacem", " %s\n", expr);
+ VG_(debugLog)(0, "aspacem", " at %s:%d (%s)\n", file,line,fn);
+ VG_(debugLog)(0, "aspacem", "Exiting now.\n");
+ VG_(exit)(1);
+}
+
+#define aspacem_assert(expr) \
+ ((void) ((expr) ? 0 : \
+ (aspacem_assert_fail(#expr, \
+ __FILE__, __LINE__, \
+ __PRETTY_FUNCTION__))))
+
+
+//--------------------------------------------------------------
+// A simple sprintf implementation, so as to avoid dependence on
+// m_libcprint.
+
static void add_to_aspacem_sprintf_buf ( HChar c, void *p )
{
HChar** aspacem_sprintf_ptr =3D p;
@@ -1380,10 +1468,12 @@
}
=20
=20
-/////////////////////////////////////////////////////////////////
+//--------------------------------------------------------------
+// Direct access to the kernel's mmap/munmap syscalls. This
+// avoids dependence on m_libcmman.
=20
-SysRes VG_(aspacem_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt pr=
ot,=20
- UInt flags, UInt fd, OffT offset)
+SysRes VG_(am_do_mmap_NO_NOTIFY)( Addr start, SizeT length, UInt prot,=20
+ UInt flags, UInt fd, OffT offset)
{
SysRes res;
# if defined(VGP_x86_linux)
@@ -1402,7 +1492,7 @@
prot, flags, fd, offset);
# elif defined(VGP_ppc32_linux)
res =3D VG_(do_syscall6)(__NR_mmap, (UWord)(start), (length),
- prot, flags, fd, offset);
+ prot, flags, fd, offset);
# else
# error Unknown platform
# endif
@@ -1410,12 +1500,14 @@
}
=20
static
-SysRes do_munmap_NATIVE(Addr start, SizeT length)
+SysRes do_munmap_NO_NOTIFY(Addr start, SizeT length)
{
return VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
}
=20
=20
+//--------------------------------------------------------------
+// Functions for extracting information about file descriptors.
=20
static=20
Bool get_inode_for_fd ( Int fd, /*OUT*/UInt* dev, /*OUT*/UInt* ino )
@@ -1430,57 +1522,54 @@
}
=20
=20
-/////////////////////////////////////////////////////////////////
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Low level access / modification of the segment array. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
=20
-static void aspacem_barf ( HChar* what )
+/* Binary search the interval array for a given address. Since the
+ array covers the entire address space the search cannot fail. */
+static Int find_nsegment_idx ( Addr a )
{
- VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: %s\n", what);
- VG_(debugLog)(0, "aspacem", "Exiting now.\n");
- VG_(exit)(1);
-}
+ Addr a_mid_lo, a_mid_hi;
+ Int mid,
+ lo =3D 0,
+ hi =3D nsegments_used-1;
+ while (True) {
+ /* current unsearched space is from lo to hi, inclusive. */
+ if (lo > hi) {
+ /* Not found. This can't happen. */
+ aspacem_barf("find_nsegment_idx: not found");
+ }
+ mid =3D (lo + hi) / 2;
+ a_mid_lo =3D nsegments[mid].start;
+ a_mid_hi =3D nsegments[mid].end;
=20
-static void aspacem_barf_toolow ( HChar* what )
-{
- VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: %s is too low.\n", what)=
;
- VG_(debugLog)(0, "aspacem", " Increase it and rebuild. "
- "Exiting now.\n");
- VG_(exit)(1);
+ if (a < a_mid_lo) { hi =3D mid-1; continue; }
+ if (a > a_mid_hi) { lo =3D mid+1; continue; }
+ aspacem_assert(a >=3D a_mid_lo && a <=3D a_mid_hi);
+ aspacem_assert(0 <=3D mid && mid < nsegments_used);
+ return mid;
+ }
}
=20
-static void aspacem_assert_fail( const HChar* expr,
- const Char* file,
- Int line,=20
- const Char* fn )
+
+/* Finds the segment containing 'a'. Only returns file/anon/resvn
+ segments. */
+NSegment* VG_(am_find_nsegment) ( Addr a )
{
- VG_(debugLog)(0, "aspacem", "Valgrind: FATAL: assertion failed:\n");
- VG_(debugLog)(0, "aspacem", " %s\n", expr);
- VG_(debugLog)(0, "aspacem", " at %s:%d (%s)\n", file,line,fn);
- VG_(debugLog)(0, "aspacem", "Exiting now.\n");
- VG_(exit)(1);
+ Int i =3D find_nsegment_idx(a);
+ aspacem_assert(i >=3D 0 && i < nsegments_used);
+ aspacem_assert(nsegments[i].start <=3D a);
+ aspacem_assert(a <=3D nsegments[i].end);
+ if (nsegments[i].kind =3D=3D SkFree)=20
+ return NULL;
+ else
+ return &nsegments[i];
}
=20
-#define aspacem_assert(expr) \
- ((void) ((expr) ? 0 : \
- (aspacem_assert_fail(#expr, \
- __FILE__, __LINE__, \
- __PRETTY_FUNCTION__))))
=20
-
-
-#define Addr_MIN ((Addr)0)
-#define Addr_MAX ((Addr)(-1ULL))
-
-
-/* Array [0 .. nsegments_used-1] of all mappings. */
-/* Sorted by .addr field. */
-/* I: len may not be zero. */
-/* I: overlapping segments are not allowed. */
-/* Each segment can optionally hold an index into the filename table. */
-
-static NSegment nsegments[VG_N_SEGMENTS];
-static Int nsegments_used =3D 0;
-
-
/* Given a pointer to a seg, tries to figure out which one it is in
nsegments[..]. Very paranoid. */
static Int segAddr_to_index ( NSegment* seg )
@@ -1496,9 +1585,10 @@
return -1;
}
=20
-/* Find the next segment along from HERE, if it is a file/anon/resvn
+
+/* Find the next segment along from 'here', if it is a file/anon/resvn
segment. */
-NSegment* VG_(next_nsegment) ( NSegment* here, Bool fwds )
+NSegment* VG_(am_next_nsegment) ( NSegment* here, Bool fwds )
{
Int i =3D segAddr_to_index(here);
if (i < 0 || i >=3D nsegments_used)
@@ -1515,96 +1605,491 @@
if (nsegments[i].kind =3D=3D SkFile=20
|| nsegments[i].kind =3D=3D SkAnon
|| nsegments[i].kind =3D=3D SkResvn)
- return &nsegments[i];
+ return &nsegments[i];
else=20
return NULL;
}
=20
=20
-ULong VG_(aspacem_get_anonsize_total)( void )
+/* Sanity checking: ensure the segment array covers the entire address
+ space exactly. */
+static void check_nsegments ( void )
{
- Int i;
- ULong total =3D 0;
- for (i =3D 0; i < nsegments_used; i++) {
- if (nsegments[i].kind !=3D SkAnon)
- continue;
- total +=3D (ULong)nsegments[i].end - (ULong)nsegments[i].start + 1UL=
L;
- }
- return total;
+ Int i;
+ aspacem_assert(nsegments_used > 0);
+ aspacem_assert(nsegments[0].start =3D=3D Addr_MIN);
+ aspacem_assert(nsegments[nsegments_used-1].end =3D=3D Addr_MAX);
+ for (i =3D 1; i < nsegments_used; i++)
+ aspacem_assert(nsegments[i-1].end+1 =3D=3D nsegments[i].start);
}
=20
-/* check the interval array */
-static void check_nsegments ( void )
+
+/* Trivial fn: return the total amount of space in anonymous mappings,
+ both for V and the client. Is used for printing stats in
+ out-of-memory messages. */
+ULong VG_(am_get_anonsize_total)( void )
{
- Int i;
- aspacem_assert(nsegments_used > 0);
- aspacem_assert(nsegments[0].start =3D=3D Addr_MIN);
- aspacem_assert(nsegments[nsegments_used-1].end =3D=3D Addr_MAX);
- for (i =3D 1; i < nsegments_used; i++)
- aspacem_assert(nsegments[i-1].end+1 =3D=3D nsegments[i].start);
+ Int i;
+ ULong total =3D 0;
+ for (i =3D 0; i < nsegments_used; i++) {
+ if (nsegments[i].kind !=3D SkAnon)
+ continue;
+ total +=3D (ULong)nsegments[i].end - (ULong)nsegments[i].start + 1=
ULL;
+ }
+ return total;
}
=20
=20
-/* Binary search the interval array for a given address. Since the
- array covers the entire address space the search cannot fail. */
-static Int find_nsegment_idx ( Addr a )
+/* Test if a piece of memory is addressable by the client with at
+ least the "prot" protection permissions by examining the underlying
+ segments.
+*/
+Bool VG_(am_is_valid_for_client)( Addr start, SizeT len, UInt prot )
{
- Addr a_mid_lo, a_mid_hi;
- Int mid,
- lo =3D 0,
- hi =3D nsegments_used-1;
- while (True) {
- /* current unsearched space is from lo to hi, inclusive. */
- if (lo > hi) {
- /* Not found. This can't happen. */
- aspacem_barf("find_nsegment_idx: not found");
+ Int i, iLo, iHi;
+ Bool needR, needW, needX;
+
+ if (len =3D=3D 0)
+ return True; /* somewhat dubious case */
+ if (start + len < start)
+ return False; /* reject wraparounds */
+
+ needR =3D toBool(prot & VKI_PROT_READ);
+ needW =3D toBool(prot & VKI_PROT_WRITE);
+ needX =3D toBool(prot & VKI_PROT_EXEC);
+
+ 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].isClient
+ && (nsegments[i].kind =3D=3D SkFile || nsegments[i].kind =3D=3D=
SkAnon)
+ && (needR ? nsegments[i].hasR : True)
+ && (needW ? nsegments[i].hasW : True)
+ && (needX ? nsegments[i].hasX : True)) {
+ /* ok */
+ } else {
+ return False;
}
- mid =3D (lo + hi) / 2;
- a_mid_lo =3D nsegments[mid].start;
- a_mid_hi =3D nsegments[mid].end;
+ }
+ return True;
+}
=20
- if (a < a_mid_lo) { hi =3D mid-1; continue; }
- if (a > a_mid_hi) { lo =3D mid+1; continue; }
- aspacem_assert(a >=3D a_mid_lo && a <=3D a_mid_hi);
- aspacem_assert(0 <=3D mid && mid < nsegments_used);
- return mid;
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Displaying the segment array. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+static HChar* show_seg_kind ( NSegment* seg )
+{
+ switch (seg->kind) {
+ case SkFree: return " ";
+ case SkAnon: return seg->isClient ? "anon" : "ANON";
+ case SkFile: return seg->isClient ? "file" : "FILE";
+ case SkResvn: return "RSVN";
+ default: return "????";
}
}
=20
-/* Find a segment, not include free-space and ones, for outside use. */
-NSegment* VG_(find_nsegment) ( Addr a )
+static HChar* show_ShrinkMode ( ShrinkMode sm )
{
- Int i =3D find_nsegment_idx(a);
- aspacem_assert(i >=3D 0 && i < nsegments_used);
- aspacem_assert(nsegments[i].start <=3D a);
- aspacem_assert(a <=3D nsegments[i].end);
- if (nsegments[i].kind =3D=3D SkFree)=20
- return NULL;
- else
- return &nsegments[i];
+ switch (sm) {
+ case SmLower: return "SmLower";
+ case SmUpper: return "SmUpper";
+ case SmFixed: return "SmFixed";
+ default: return "Sm?????";
+ }
}
=20
+static void show_Addr_concisely ( /*OUT*/HChar* buf, Addr aA )
+{
+ HChar* fmt;
+ ULong a =3D (ULong)aA;
+ if (a >=3D 10000000ULL) {
+ fmt =3D "%6llum";
+ a /=3D 1024*1024ULL;
+ } else {
+ fmt =3D "%7llu";
+ }
+ aspacem_sprintf(buf, fmt, a);
+}
=20
+static void show_nsegment ( Int logLevel, Int segNo, NSegment* seg )
+{
+ HChar len_buf[20];
+ ULong len =3D ((ULong)seg->end) - ((ULong)seg->start) + 1;
+ show_Addr_concisely(len_buf, len);
=20
-/* Limits etc */
+ switch (seg->kind) {
=20
-// The smallest address that aspacem will try to allocate
-static Addr aspacem_minAddr;
+ case SkFree:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %08llx-%08llx %s\n",
+ segNo, show_seg_kind(seg),
+ (ULong)seg->start, (ULong)seg->end, len_buf
+ );
+ break;
=20
-// The largest address that aspacem will try to allocate
-static Addr aspacem_maxAddr;
+ case SkAnon:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %08llx-%08llx %s %c%c%c%c d=3D0x%03x i=3D%-7d o=3D%=
-7lld (%d)\n",
+ segNo, show_seg_kind(seg),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',=20
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',=20
+ seg->dev, seg->ino, (Long)seg->offset, seg->fnIdx
+ );
+ break;
=20
-// Where aspacem will start looking for client space
-static Addr aspacem_cStart;
+ case SkFile:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %08llx-%08llx %s %c%c%c%c d=3D0x%03x i=3D%-7d o=3D%=
-7lld (%d)\n",
+ segNo, show_seg_kind(seg),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',=20
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',=20
+ seg->dev, seg->ino, (Long)seg->offset, seg->fnIdx
+ );
+ break;
=20
-// Where aspacem will start looking for Valgrind space
-static Addr aspacem_vStart;
+ case SkResvn:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: %s %08llx-%08llx %s %c%c%c%c %s\n",
+ segNo, show_seg_kind(seg),
+ (ULong)seg->start, (ULong)seg->end, len_buf,
+ seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-',=20
+ seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-',=20
+ show_ShrinkMode(seg->smode)
+ );
+ break;
=20
+ default:
+ VG_(debugLog)(
+ logLevel, "aspacem",
+ "%3d: ???? UNKNOWN SEGMENT KIND\n",=20
+ segNo=20
+ );
+ break;
+ }
+}
=20
-Bool VG_(aspacem_getAdvisory) ( MapRequest* req,=20
- Bool forClient,=20
- /*OUT*/Addr* result )
+/* Print out the segment array (debugging only!). */
+void VG_(am_show_nsegments) ( Int logLevel, HChar* who )
{
+ Int i;
+ VG_(debugLog)(logLevel, "aspacem",
+ "<<< SHOW_SEGMENTS: %s (%d segments, %d segnames)\n",=20
+ who, segments_used, segnames_used);
+ for (i =3D 0; i < segnames_used; i++) {
+ if (!segnames[i].inUse)
+ continue;
+ VG_(debugLog)(logLevel, "aspacem",
+ "(%2d) %s\n", i, segnames[i].fname);
+ }
+ for (i =3D 0; i < nsegments_used; i++)
+ show_nsegment( logLevel, i, &nsegments[i] );
+ VG_(debugLog)(logLevel, "aspacem",
+ ">>>\n");
+}
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Modifying the segment array, and constructing segments. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Add SEG to the collection, deleting/truncating any it overlaps.
+ This deals with all the tricky cases of splitting up segments as
+ needed. */
+
+static void add_segment ( NSegment* seg )
+{
+ Int nDeld, i, j, k;
+ Addr iStart, iEnd;
+
+ Addr dStart =3D seg->start;
+ Addr dEnd =3D seg->end;
+
+ aspacem_assert(dStart <=3D dEnd);
+ aspacem_assert(VG_IS_PAGE_ALIGNED(dStart));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(dEnd+1));
+
+ nDeld =3D 0;
+
+ /* Iterate over all segments, considering how each interacts with
+ the new address range dStart .. dEnd. */
+
+ for (i =3D 0; i < nsegments_used; i++) {
+
+ nsegments[i].mark =3D False;
+
+ iStart =3D nsegments[i].start;
+ iEnd =3D nsegments[i].end;
+
+ /* no-overlap cases */
+ if (iEnd < dStart) continue;
+ if (dEnd < iStart) continue;
+
+ if (dStart <=3D iStart && iEnd <=3D dEnd) {
+ /* i is completely overlapped. Mark it for deletion. */
+ nsegments[i].mark =3D True;
+ nDeld++;
+ continue;
+ }
+
+ if (iStart < dStart && iEnd > dEnd) {
+ /* deleted interval is completely contained within i. This
+ means i has to be split into two pieces. As a result,
+ first move the following elements up by one place to make
+ space for the new part. */
+ if (nsegments_used >=3D VG_N_SEGMENTS)
+ aspacem_barf_toolow("VG_N_SEGMENTS");
+ for (j =3D nsegments_used-1; j > i; j--)
+ nsegments[j+1] =3D nsegments[j];
+ nsegments_used++;
+ nsegments[i+1] =3D nsegments[i];
+ nsegments[i].end =3D dStart-1;
+ nsegments[i+1].start =3D dEnd+1;
+ nsegments[i+1].offset +=3D (nsegments[i+1].start - nsegments[i]=
.start);
+ continue;
+ }
+
+ if (iStart < dStart && iEnd <=3D dEnd && iEnd >=3D dStart) {
+ /* interval to be deleted straddles upper boundary of i. */
+ nsegments[i].end =3D dStart-1;
+ continue;
+ }
+
+ if (iEnd > dEnd && iStart >=3D dStart && iStart <=3D dEnd) {
+ /* interval to be deleted straddles lower boundary of i. */
+ nsegments[i].offset +=3D (dEnd+1 - nsegments[i].start);
+ nsegments[i].start =3D dEnd+1;
+ continue;
+ }
+
+ /* I don't think we can get here. */
+ aspacem_assert(0);
+ }
+
+ /* Get rid of the intervals marked for deletion. */
+ if (nDeld > 0) {
+ j =3D 0;
+ for (i =3D 0; i < nsegments_used; i++) {
+ if (nsegments[i].mark)
+ continue;
+ nsegments[j] =3D nsegments[i];
+ j++;
+ }
+ nsegments_used -=3D nDeld;
+ }
+
+ /* At this point, there should be a gap dStart .. dEnd inclusive.
+ Find the gap and insert the new interval in it. Set k so that
+ all entries >=3D k must be moved up 1, and the new interval placed
+ at k. */
+ if (nsegments_used >=3D VG_N_SEGMENTS)
+ aspacem_barf_toolow("VG_N_SEGMENTS");
+ if (nsegments_used =3D=3D 0) {
+ k =3D 0;
+ } else {
+ for (i =3D 0; i < nsegments_used; i++) {
+ if (dEnd+1 =3D=3D nsegments[i].start=20
+ && /*guard against wraparound*/dEnd+1 > dEnd)
+ break;
+ }
+ k =3D i;
+ }
+
+ aspacem_assert(k >=3D 0 && k <=3D nsegments_used);
+ for (j =3D nsegments_used-1; j >=3D k; j--)
+ nsegments[j+1] =3D nsegments[j];
+ nsegments_used++;
+
+ nsegments[k] =3D *seg;
+
+ check_nsegments();
+}
+
+
+/* Clear out an NSegment record. */
+
+static void init_nsegment ( /*OUT*/NSegment* seg )
+{
+ seg->kind =3D SkAnon;
+ seg->isClient =3D False;
+ seg->start =3D 0;
+ seg->end =3D 0;
+ seg->smode =3D SmFixed;
+ seg->dev =3D 0;
+ seg->ino =3D 0;
+ seg->offset =3D 0;
+ seg->fnIdx =3D -1;
+ seg->hasR =3D seg->hasR =3D seg->hasW =3D seg->hasT =3D False;
+ seg->mark =3D False;
+}
+
+/* Make an NSegment which holds a reservation. */
+
+static void init_resvn ( /*OUT*/NSegment* seg, Addr start, Addr end )
+{
+ aspacem_assert(start < end);
+ aspacem_assert(VG_IS_PAGE_ALIGNED(start));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(end+1));
+ init_nsegment(seg);
+ seg->kind =3D SkResvn;
+ seg->start =3D start;
+ seg->end =3D end;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Startup, including reading /proc/self/maps. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+static void read_maps_callback ( Addr addr, SizeT len, UInt prot,
+ UInt dev, UInt ino, ULong offset,=20
+ const UChar* filename )
+{
+ NSegment seg;
+ init_nsegment( &seg );
+ seg.start =3D addr;
+ seg.end =3D addr+len-1;
+ seg.dev =3D dev;
+ seg.ino =3D ino;
+ seg.offset =3D offset;
+ seg.hasR =3D toBool(prot & VKI_PROT_READ);
+ seg.hasW =3D toBool(prot & VKI_PROT_WRITE);
+ seg.hasX =3D toBool(prot & VKI_PROT_EXEC);
+ seg.hasT =3D False;
+
+ seg.kind =3D SkAnon;
+ if (filename) {=20
+ seg.kind =3D SkFile;
+ seg.fnIdx =3D allocate_segname( filename );
+ }
+
+ show_nsegment( 2,0, &seg );
+ add_segment( &seg );
+}
+
+/* Initialise the address space manager, setting up the initial
+ segment list, and reading /proc/self/maps into it. This must
+ be called before any other function.
+
+ Takes a pointer to the SP at the time V gained control. This is
+ taken to be the highest usable address (more or less). Based on
+ that (and general consultation of tea leaves, etc) return a
+ suggested end address for the client's stack. */
+
+Addr VG_(am_startup) ( Addr sp_at_startup )
+{
+ NSegment seg;
+ Addr suggested_clstack_top;
+
+ aspacem_assert(sizeof(Word) =3D=3D sizeof(void*));
+ aspacem_assert(sizeof(Addr) =3D=3D sizeof(void*));
+ aspacem_assert(sizeof(SizeT) =3D=3D sizeof(void*));
+ aspacem_assert(sizeof(SSizeT) =3D=3D sizeof(void*));
+
+ /* Add a single interval covering the entire address space. */
+ init_nsegment(&seg);
+ seg.kind =3D SkFree;
+ seg.start =3D Addr_MIN;
+ seg.end =3D Addr_MAX;
+ nsegments[0] =3D seg;
+ nsegments_used =3D 1;
+
+ /* Establish address limits and block out unusable parts
+ accordingly. */
+
+ VG_(debugLog)(2, "aspacem",=20
+ " sp_at_startup =3D 0x%llx (supplied)\n",=20
+ (ULong)sp_at_startup );
+
+ aspacem_minAddr =3D (Addr) 0x04000000; // 64M
+
+# if VG_WORDSIZE =3D=3D 8
+ aspacem_maxAddr =3D (Addr)0x400000000 - 1; // 16G
+# else
+ aspacem_maxAddr =3D VG_PGROUNDDN( sp_at_startup ) - 1;
+# endif
+
+ aspacem_cStart =3D aspacem_minAddr; // 64M
+ aspacem_vStart =3D VG_PGROUNDUP((aspacem_minAddr + aspacem_maxAddr + =
1) / 2);
+
+ suggested_clstack_top =3D aspacem_maxAddr - 16*1024*1024ULL
+ + VKI_PAGE_SIZE;
+
+ aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_minAddr));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_maxAddr + 1));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_cStart));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_vStart));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(suggested_clstack_top + 1));
+
+ VG_(debugLog)(2, "aspacem",=20
+ " minAddr =3D 0x%08llx (computed)\n",=20
+ (ULong)aspacem_minAddr);
+ VG_(debugLog)(2, "aspacem",=20
+ " maxAddr =3D 0x%08llx (computed)\n",=20
+ (ULong)aspacem_maxAddr);
+ VG_(debugLog)(2, "aspacem",=20
+ " cStart =3D 0x%08llx (computed)\n",=20
+ (ULong)aspacem_cStart);
+ VG_(debugLog)(2, "aspacem",=20
+ " vStart =3D 0x%08llx (computed)\n",=20
+ (ULong)aspacem_vStart);
+ VG_(debugLog)(2, "aspacem",=20
+ "suggested_clstack_top =3D 0x%08llx (computed)\n",=20
+ (ULong)suggested_clstack_top);
+
+ if (aspacem_cStart > Addr_MIN) {
+ init_resvn(&seg, Addr_MIN, aspacem_cStart-1);
+ add_segment(&seg);
+ }
+ if (aspacem_maxAddr < Addr_MAX) {
+ init_resvn(&seg, aspacem_maxAddr+1, Addr_MAX);
+ add_segment(&seg);
+ }
+
+ /* Create a 1-page reservation at the notional initial
+ client/valgrind boundary. This isn't strictly necessary, but
+ because the advisor does first-fit and starts searches for
+ valgrind allocations at the boundary, this is kind of necessary
+ in order to get it to start allocating in the right place. */
+ init_resvn(&seg, aspacem_vStart, aspacem_vStart + VKI_PAGE_SIZE - 1)=
;
+ add_segment(&seg);
+
+ VG_(am_show_nsegments)(2, "Initial layout");
+
+ VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n");
+ VG_(parse_procselfmaps) ( read_maps_callback );
+
+ VG_(am_show_nsegments)(2, "With contents of /proc/self/maps");
+
+ return suggested_clstack_top;
+}
+
+
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- The core query-notify mechanism. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
+
+/* Query aspacem to ask where a mapping should go. */
+
+Bool VG_(am_get_advisory) ( MapRequest* req,=20
+ Bool forClient,=20
+ /*OUT*/Addr* result )
+{
/* This function implements allocation policy.
=20
The nature of the allocation request is determined by req, which
@@ -1660,9 +2145,11 @@
=20
aspacem_assert(nsegments_used > 0);
=20
- VG_(show_nsegments)(0,"getAdvisory");
- VG_(debugLog)(0,"aspacem", "getAdvisory 0x%llx %lld\n",=20
- (ULong)req->start, (ULong)req->len);
+ if (0) {
+ VG_(am_show_nsegments)(0,"getAdvisory");
+ VG_(debugLog)(0,"aspacem", "getAdvisory 0x%llx %lld\n",=20
+ (ULong)req->start, (ULong)req->len);
+ }
=20
/* Reject zero-length requests */
if (req->len =3D=3D 0)
@@ -1782,394 +2269,98 @@
}
=20
=20
+/* Notifies aspacem that the client completed an mmap successfully.
+ The segment array is updated accordingly. */
=20
-static void init_nsegment ( /*OUT*/NSegment* seg )
+void=20
+VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags,
+ Int fd, SizeT offset )
{
- seg->kind =3D SkAnon;
- seg->isClient =3D False;
- seg->start =3D 0;
- seg->end =3D 0;
- seg->smode =3D SmFixed;
- seg->dev =3D 0;
- seg->ino =3D 0;
- seg->offset =3D 0;
- seg->fnIdx =3D -1;
- seg->hasR =3D seg->hasR =3D seg->hasW =3D seg->hasT =3D False;
- seg->mark =3D False;
-}
+ HChar buf[VKI_PATH_MAX];
+ UInt dev, ino;
+ NSegment seg;
=20
-static void init_resvn ( /*OUT*/NSegment* seg, Addr start, Addr end )
-{
- aspacem_assert(start < end);
- aspacem_assert(VG_IS_PAGE_ALIGNED(start));
- aspacem_assert(VG_IS_PAGE_ALIGNED(end+1));
- init_nsegment(seg);
- seg->kind =3D SkResvn;
- seg->start =3D start;
- seg->end =3D end;
+ aspacem_assert(len > 0);
+ aspacem_assert(VG_IS_PAGE_ALIGNED(a));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(len));
+ init_nsegment( &seg );
+ seg.kind =3D (flags & VKI_MAP_ANONYMOUS) ? SkAnon : SkFile;
+ seg.isClient =3D True;
+ seg.start =3D a;
+ seg.end =3D a + len - 1;
+ seg.offset =3D offset;
+ seg.hasR =3D toBool(prot & VKI_PROT_READ);
+ seg.hasW =3D toBool(prot & VKI_PROT_WRITE);
+ seg.hasX =3D toBool(prot & VKI_PROT_EXEC);
+ /* TODO: what about seg.hasT ? */
+ if (get_inode_for_fd(fd, &dev, &ino)) {
+ seg.dev =3D dev;
+ seg.ino =3D ino;
+ }
+ if (get_name_for_fd(fd, buf, VKI_PATH_MAX)) {
+ seg.fnIdx =3D allocate_segname( buf );
+ }
+ add_segment( &seg );
}
=20
-static HChar* show_seg_kind ( NSegment* seg )
-{
- switch (seg->kind) {
- case SkFree: return " ";
- case SkAnon: return seg->isClient ? "anon" : "ANON";
- case SkFile: return seg->isClient ? "file" : "FILE";
- case SkResvn: return "RSVN";
- default: return "????";
- }
-}
+/* Notifies aspacem that the client completed an mprotect
+ successfully. The segment array is updated accordingly. */
=20
-static HChar* show_ShrinkMode ( ShrinkMode sm )
+void VG_(am_notify_client_mprotect)( Addr start, SizeT len, UInt prot )
{
- switch (sm) {
- case SmLower: return "SmLower";
- case SmUpper: return "SmUpper";
- case SmFixed: return "SmFixed";
- default: return "Sm?????";
- }
-}
+ Int iLo, iHi;
=20
-static void show_Addr_concisely ( /*OUT*/HChar* buf, Addr aA )
-{
- HChar* fmt;
- ULong a =3D (ULong)aA;
- if (a >=3D 10000000ULL) {
- fmt =3D "%6llum";
-a /=3D 1024*1024ULL;
- } else {
- fmt =3D "%7llu";
- }
- aspacem_sprintf(buf, fmt, a);
-}
+ if (len =3D=3D 0)
+ return;
=20
-static void show_nsegment ( Int logLevel, Int segNo, NSegment* seg )
-{
- HChar len_buf[20];
- ULong len =3D ((ULong)seg->end) - ((ULong)seg->start) + 1;
- show_Addr_concisely(len_buf, len);
+ iLo =3D find_nsegment_idx(start);
+ iHi =3D find_nsegment_idx(start + len - 1);
=20
- switch (seg->kind) {
- case SkFree: {
- VG_(debugLog)(
- logLevel, "aspacem",
- "%3d: %s %08llx-%08llx %s\n",
- segNo,
- show_seg_kind(seg),
- (ULong)seg->start,
- (ULong)seg->end,
- len_buf
- );
- break;
- }
-
- case SkAnon:
- VG_(debugLog)(
- logLevel, "aspacem",
- "%3d: %s %08llx-%08llx %s %c%c%c%c d=3D0x%03x i=3D%-7d o=3D%-7lld (=
%d)\n",
- segNo,
- show_seg_kind(seg),
- (ULong)seg->start,
- (ULong)seg->end,
- len_buf,
- seg->hasR ? 'r' : '-',=20
- seg->hasW ? 'w' : '-',=20
- seg->hasX ? 'x' : '-',=20
- seg->hasT ? 'T' : '-',=20
- seg->dev,
- seg->ino,
- (Long)seg->offset,
- seg->fnIdx
- );
- break;
- case SkFile:
- VG_(debugLog)(
- logLevel, "aspacem",
- "%3d: %s %08llx-%08llx %s %c%c%c%c d=3D0x%03x i=3D%-7d o=3D%-7lld (=
%d)\n",
- segNo,
- show_seg_kind(seg),
- (ULong)seg->start,
- (ULong)seg->end,
- len_buf,
- seg->hasR ? 'r' : '-',=20
- seg->hasW ? 'w' : '-',=20
- seg->hasX ? 'x' : '-',=20
- seg->hasT ? 'T' : '-',=20
- seg->dev,
- seg->ino,
- (Long)seg->offset,
- seg->fnIdx
- );
- break;
- case SkResvn:
- VG_(debugLog)(
- logLevel, "aspacem",
- "%3d: %s %08llx-%08llx %s %c%c%c%c %s\n",
- segNo,
- show_seg_kind(seg),
- (ULong)seg->start,
- (ULong)seg->end,
- len_buf,
- seg->hasR ? 'r' : '-',=20
- seg->hasW ? 'w' : '-',=20
- seg->hasX ? 'x' : '-',=20
- seg->hasT ? 'T' : '-',=20
- show_ShrinkMode(seg->smode)
- );
- break;
-
- default:
- VG_(debugLog)(
- logLevel, "aspacem",
- "%3d: ???? UNKNOWN SEGMENT KIND\n",
-segNo );
- break;
- }
-}
-
-/* Print out the segment array (debugging only!). */
-void VG_(show_nsegments) ( Int logLevel, HChar* who )
-{
- Int i;
- VG_(debugLog)(logLevel, "aspacem",
- "<<< SHOW_SEGMENTS: %s (%d segments, %d segnames)\n",=20
- who, segments_used, segnames_used);
- for (i =3D 0; i < segnames_used; i++) {
- if (!segnames[i].inUse)
- continue;
- VG_(debugLog)(logLevel, "aspacem",
- "(%2d) %s\n", i, segnames[i].fname);
+ if (iLo =3D=3D iHi=20
+ && nsegments[iLo].start =3D=3D start=20
+ && nsegments[iLo].end+1 =3D=3D start+len
+ && (nsegments[iLo].kind =3D=3D SkFile || nsegments[iLo].kind =3D=3D=
SkAnon)) {
+ nsegments[iLo].hasR =3D toBool(prot & VKI_PROT_READ);
+ nsegments[iLo].hasW =3D toBool(prot & VKI_PROT_WRITE);
+ nsegments[iLo].hasX =3D toBool(prot & VKI_PROT_EXEC);
+ return;
}
- for (i =3D 0; i < nsegments_used; i++)
- show_nsegment( logLevel, i, &nsegments[i] );
- VG_(debugLog)(logLevel, "aspacem",
- ">>>\n");
-}
=20
-
-/* Add SEG to the collection, deleting/truncating any it overlaps */
-static void add_segment ( NSegment* seg )
-{
- Int nDeld, i, j, k;
- Addr iStart, iEnd;
-
- Addr dStart =3D seg->start;
- Addr dEnd =3D seg->end;
-
- aspacem_assert(dStart <=3D dEnd);
- aspacem_assert(VG_IS_PAGE_ALIGNED(dStart));
- aspacem_assert(VG_IS_PAGE_ALIGNED(dEnd+1));
-
- nDeld =3D 0;
-
- for (i =3D 0; i < nsegments_used; i++) {
-
- nsegments[i].mark =3D False;
-
- iStart =3D nsegments[i].start;
- iEnd =3D nsegments[i].end;
-
- /* no-overlap cases */
- if (iEnd < dStart) continue;
- if (dEnd < iStart) continue;
-
- if (dStart <=3D iStart && iEnd <=3D dEnd) {
- /* i is completely overlapped. Mark it for deletion. */
- nsegments[i].mark =3D True;
- nDeld++;
- continue;
- }
-
- if (iStart < dStart && iEnd > dEnd) {
- /* deleted interval is completely contained within i. This
- means i has to be split into two pieces. As a result, first
- move the following elements up by one place to make space for
- the new part. */
- if (nsegments_used >=3D VG_N_SEGMENTS)
- aspacem_barf_toolow("VG_N_SEGMENTS");
- for (j =3D nsegments_used-1; j > i; j--)
- nsegments[j+1] =3D nsegments[j];
- nsegments_used++;
- nsegments[i+1] =3D nsegments[i];
- nsegments[i].end =3D dStart-1;
- nsegments[i+1].start =3D dEnd+1;
- nsegments[i+1].offset +=3D (nsegments[i+1].start - nsegments[i].st=
art);
- continue;
- }
-
- if (iStart < dStart && iEnd <=3D dEnd && iEnd >=3D dStart) {
- /* interval to be deleted straddles upper boundary of i. */
- nsegments[i].end =3D dStart-1;
- continue;
- }
-
- if (iEnd > dEnd && iStart >=3D dStart && iStart <=3D dEnd) {
- /* interval to be deleted straddles lower boundary of i. */
- nsegments[i].offset +=3D (dEnd+1 - nsegments[i].start);
- nsegments[i].start =3D dEnd+1;
- continue;
- }
-
- /* I don't think we can get here. */
- aspacem_assert(0);
- }
-
- /* Get rid of the intervals marked for deletion. */
- if (nDeld > 0) {
- j =3D 0;
- for (i =3D 0; i < nsegments_used; i++) {
- if (nsegments[i].mark)
- continue;
- nsegments[j] =3D nsegments[i];
- j++;
- }
- nsegments_used -=3D nDeld;
- }
-
- /* At this point, there should be a gap dStart .. dEnd inclusive.
- Find the gap and insert the new interval in it. Set k so that
- all entries >=3D k must be moved up 1, and the new interval placed
- at k. */
- if (nsegments_used >=3D VG_N_SEGMENTS)
- aspacem_barf_toolow("VG_N_SEGMENTS");
- if (nsegments_used =3D=3D 0) {
- k =3D 0;
- } else {
- for (i =3D 0; i < nsegments_used; i++)
- if (dEnd+1 =3D=3D nsegments[i].start=20
- && /*guard against wraparound*/dEnd+1 > dEnd)
- break;
- k =3D i;
- }
-
- aspacem_assert(k >=3D 0 && k <=3D nsegments_used);
- for (j =3D nsegments_used-1; j >=3D k; j--)
- nsegments[j+1] =3D nsegments[j];
- nsegments_used++;
-
- nsegments[k] =3D *seg;
-
- check_nsegments();
+ /* FIXME: unhandled general case */
+ aspacem_barf("notify_mprotect general case");
}
=20
=20
+/* Notifies aspacem that the client completed an munmap successfully.
+ The segment array is updated accordingly. */
=20
-static void read_maps_callback (=20
- Addr addr, SizeT len, UInt prot,
- UInt dev, UInt ino, ULong foff, const UChar* filename )
+void VG_(am_notify_client_munmap)( Addr start, SizeT len )
{
- NSegment seg;
- init_nsegment( &seg );
- seg.start =3D addr;
- seg.end =3D addr+len-1;
- seg.dev =3D dev;
- seg.ino =3D ino;
- seg.offset =3D foff;
- seg.hasR =3D toBool(prot & VKI_PROT_READ);
- seg.hasW =3D toBool(prot & VKI_PROT_WRITE);
- seg.hasX =3D toBool(prot & VKI_PROT_EXEC);
+ NSegment seg;
=20
- seg.kind =3D SkAnon;
- if (filename) {=20
- seg.kind =3D SkFile;
- seg.fnIdx =3D allocate_segname( filename );
- }
+ if (len =3D=3D 0)
+ return;
=20
- show_nsegment( 2,0, &seg );
- add_segment( &seg );
+ init_nsegment( &seg );
+ seg.kind =3D SkFree;
+ seg.start =3D start;
+ seg.end =3D start + len - 1;
+ add_segment( &seg );
}
=20
-Addr VG_(new_aspacem_start) ( Addr sp_at_startup )
-{
- NSegment seg;
- Addr suggested_clstack_top;
=20
- aspacem_assert(sizeof(Word) =3D=3D sizeof(void*));
- aspacem_assert(sizeof(Addr) =3D=3D sizeof(void*));
- aspacem_assert(sizeof(SizeT) =3D=3D sizeof(void*));
- aspacem_assert(sizeof(SSizeT) =3D=3D sizeof(void*));
+/*-----------------------------------------------------------------*/
+/*--- ---*/
+/*--- Handling mappings which do not arise directly from the ---*/
+/*--- simulation of the client. ---*/
+/*--- ---*/
+/*-----------------------------------------------------------------*/
=20
- /* Add a single interval covering the entire address space. */
- init_nsegment(&seg);
- seg.kind =3D SkFree;
- seg.start =3D Addr_MIN;
- seg.end =3D Addr_MAX;
- nsegments[0] =3D seg;
- nsegments_used =3D 1;
+/* Map a file at a fixed address for the client, and update the
+ segment array accordingly. */
=20
- /* Establish address limits and block out unusable parts
- accordingly. */
-
- VG_(debugLog)(2, "aspacem",=20
- " sp_at_startup =3D 0x%llx (supplied)\n",=20
- (ULong)sp_at_startup );
-
- aspacem_minAddr =3D (Addr) 0x04000000; // 64M
-
-# if VG_WORDSIZE =3D=3D 8
- aspacem_maxAddr =3D (Addr)0x400000000 - 1; // 16G
-# else
- aspacem_maxAddr =3D VG_PGROUNDDN( sp_at_startup ) - 1;
-# endif
-
- aspacem_cStart =3D aspacem_minAddr; // 64M
- aspacem_vStart =3D VG_PGROUNDUP((aspacem_minAddr + aspacem_maxAddr + =
1) / 2);
-
- suggested_clstack_top =3D aspacem_maxAddr - 16*1024*1024ULL
- + VKI_PAGE_SIZE;
-
- aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_minAddr));
- aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_maxAddr + 1));
- aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_cStart));
- aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_vStart));
- aspacem_assert(VG_IS_PAGE_ALIGNED(suggested_clstack_top + 1));
-
- VG_(debugLog)(2, "aspacem",=20
- " minAddr =3D 0x%08llx (computed)\n",=20
- (ULong)aspacem_minAddr);
- VG_(debugLog)(2, "aspacem",=20
- " maxAddr =3D 0x%08llx (computed)\n",=20
- (ULong)aspacem_maxAddr);
- VG_(debugLog)(2, "aspacem",=20
- " cStart =3D 0x%08llx (computed)\n",=20
- (ULong)aspacem_cStart);
- VG_(debugLog)(2, "aspacem",=20
- " vStart =3D 0x%08llx (computed)\n",=20
- (ULong)aspacem_vStart);
- VG_(debugLog)(2, "aspacem",=20
- "suggested_clstack_top =3D 0x%08llx (computed)\n",=20
- (ULong)suggested_clstack_top);
-
- if (aspacem_cStart > Addr_MIN) {
- init_resvn(&seg, Addr_MIN, aspacem_cStart-1);
- add_segment(&seg);
- }
- if (aspacem_maxAddr < Addr_MAX) {
- init_resvn(&seg, aspacem_maxAddr+1, Addr_MAX);
- add_segment(&seg);
- }
-
- /* Create a 1-page reservation at the notional initial
- client/valgrind boundary. This isn't strictly necessary, but
- because the advisor does first-fit and starts searches for
- valgrind allocations at the boundary, this is kind of necessary
- in order to get it to start allocating in the right place. */
- init_resvn(&seg, aspacem_vStart, aspacem_vStart + VKI_PAGE_SIZE - 1)=
;
- add_segment(&seg);
-
- VG_(show_nsegments)(2, "Initial layout");
-
- VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n");
- VG_(parse_procselfmaps) ( read_maps_callback );
-
- VG_(show_nsegments)(2, "With contents of /proc/self/maps");
-
- return suggested_clstack_top;
-}
-
-
-SysRes VG_(mmap_file_fixed_client)
- ( void* startV, SizeT length, Int prot, Int fd, SizeT offset )
+SysRes VG_(am_mmap_file_fixed_client)
+ ( Addr start, SizeT length, UInt prot, Int fd, SizeT offset )
{
SysRes sres;
NSegment seg;
@@ -2179,10 +2370,7 @@
UInt dev, ino;
HChar buf[VKI_PATH_MAX];
=20
- Addr start =3D (Addr)startV;=20
-=20
/* Not allowable. */
- /* Not allowable. */
if (length =3D=3D 0 || !VG_IS_PAGE_ALIGNED(start))
return VG_(mk_SysRes_Error)( VKI_EINVAL );
=20
@@ -2190,14 +2378,14 @@
req.rkind =3D MFixed;
req.start =3D start;
req.len =3D length;
- ok =3D VG_(aspacem_getAdvisory)( &req, True/*client*/, &advised );
+ ok =3D VG_(am_get_advisory)( &req, True/*client*/, &advised );
if (!ok || advised !=3D start)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
=20
/* We have been advised that the mapping is allowable at the
specified address. So hand it off to the kernel, and propagate
any resulting failure immediately. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
start, length, prot,=20
VKI_MAP_FIXED|VKI_MAP_PRIVATE,=20
fd, offset=20
@@ -2209,7 +2397,7 @@
/* I don't think this can happen. It means the kernel made a
fixed map succeed but not at the requested location. Try to
repair the damage, then return saying the mapping failed. */
- (void)do_munmap_NATIVE( sres.val, length );
+ (void)do_munmap_NO_NOTIFY( sres.val, length );
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
=20
@@ -2236,8 +2424,10 @@
}
=20
=20
-SysRes VG_(mmap_anon_fixed_client)
- ( void* startV, SizeT length, Int prot )
+/* Map anonymously at a fixed address for the client, and update
+ the segment array accordingly. */
+
+SysRes VG_(am_mmap_anon_fixed_client) ( Addr start, SizeT length, UInt p=
rot )
{
SysRes sres;
NSegment seg;
@@ -2245,8 +2435,6 @@
Bool ok;
MapRequest req;
=20
- Addr start =3D (Addr)startV;=20
-=20
/* Not allowable. */
if (length =3D=3D 0 || !VG_IS_PAGE_ALIGNED(start))
return VG_(mk_SysRes_Error)( VKI_EINVAL );
@@ -2255,14 +2443,14 @@
req.rkind =3D MFixed;
req.start =3D start;
req.len =3D length;
- ok =3D VG_(aspacem_getAdvisory)( &req, True/*client*/, &advised );
+ ok =3D VG_(am_get_advisory)( &req, True/*client*/, &advised );
if (!ok || advised !=3D start)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
=20
/* We have been advised that the mapping is allowable at the
specified address. So hand it off to the kernel, and propagate
any resulting failure immediately. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
start, length, prot,=20
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,=20
0, 0=20
@@ -2274,7 +2462,7 @@
/* I don't think this can happen. It means the kernel made a
fixed map succeed but not at the requested location. Try to
repair the damage, then return saying the mapping failed. */
- (void)do_munmap_NATIVE( sres.val, length );
+ (void)do_munmap_NO_NOTIFY( sres.val, length );
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
=20
@@ -2293,8 +2481,10 @@
}
=20
=20
-SysRes VG_(mmap_anon_float_client)
- ( SizeT length, Int prot )
+/* Map anonymously at an unconstrained address for the client, and
+ update the segment array accordingly. */
+
+SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot )
{
SysRes sres;
NSegment seg;
@@ -2310,14 +2500,14 @@
req.rkind =3D MAny;
req.start =3D 0;
req.len =3D length;
- ok =3D VG_(aspacem_getAdvisory)( &req, True/*client*/, &advised );
+ ok =3D VG_(am_get_advisory)( &req, True/*client*/, &advised );
if (!ok)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
=20
/* We have been advised that the mapping is allowable at the
advised address. So hand it off to the kernel, and propagate
any resulting failure immediately. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
advised, length, prot,=20
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,=20
0, 0=20
@@ -2329,7 +2519,7 @@
/* I don't think this can happen. It means the kernel made a
fixed map succeed but not at the requested location. Try to
repair the damage, then return saying the mapping failed. */
- (void)do_munmap_NATIVE( sres.val, length );
+ (void)do_munmap_NO_NOTIFY( sres.val, length );
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
=20
@@ -2348,7 +2538,11 @@
}
=20
=20
-SysRes VG_(map_anon_float_valgrind)( SizeT length )
+/* Map anonymously at an unconstrained address for V, and update the
+ segment array accordingly. This is fundamentally how V allocates
+ itself more address space when needed. */
+
+SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length )
{
SysRes sres;
NSegment seg;
@@ -2364,14 +2558,14 @@
req.rkind =3D MAny;
req.start =3D 0;
req.len =3D length;
- ok =3D VG_(aspacem_getAdvisory)( &req, False/*valgrind*/, &advised );
+ ok =3D VG_(am_get_advisory)( &req, False/*valgrind*/, &advised );
if (!ok)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
=20
/* We have been advised that the mapping is allowable at the
specified address. So hand it off to the kernel, and propagate
any resulting failure immediately. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
advised, length,=20
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,=20
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,=20
@@ -2384,7 +2578,7 @@
/* I don't think this can happen. It means the kernel made a
fixed map succeed but not at the requested location. Try to
repair the damage, then return saying the mapping failed. */
- (void)do_munmap_NATIVE( sres.val, length );
+ (void)do_munmap_NO_NOTIFY( sres.val, length );
return VG_(mk_SysRes_Error)( VKI_EINVAL );
}
=20
@@ -2403,32 +2597,11 @@
}
=20
=20
-SysRes VG_(munmap_client)( Addr base, SizeT length )
-{
- NSegment seg;
- SysRes sres;
-
- if (length =3D=3D 0 || !VG_IS_PAGE_ALIGNED(base))
- return VG_(mk_SysRes_Error)( VKI_EINVAL );
-
- sres =3D do_munmap_NATIVE( base, length );
- if (sres.isError)
- return sres;
-
- init_nsegment( &seg );
- seg.kind =3D SkFree;
- seg.start =3D base;
- seg.end =3D seg.start + VG_PGROUNDUP(length) - 1;
- add_segment( &seg );
-
- return sres;
-}
-
-
/* See comment on prototype in pub_core_aspacemgr.h for a description
of this. */
-Bool VG_(create_reservation) ( Addr start, SizeT length,=20
- ShrinkMode smode, SSizeT extra )
+
+Bool VG_(am_create_reservation) ( Addr start, SizeT length,=20
+ ShrinkMode smode, SSizeT extra )
{
Int startI, endI;
NSegment seg;
@@ -2467,9 +2640,9 @@
aspacem_assert(end2 <=3D nsegments[startI].end);
=20
init_nsegment( &seg );
- seg.kind =3D SkResvn;
+ seg.kind =3D SkResvn;
seg.start =3D start1; /* NB: extra space is not included in the rese=
rvation. */
- seg.end =3D end1;
+ seg.end =3D end1;
seg.smode =3D smode;
add_segment( &seg );
return True;
@@ -2478,7 +2651,8 @@
=20
/* See comment on prototype in pub_core_aspacemgr.h for a description
of this. */
-Bool VG_(extend_into_adjacent_reservation)( NSegment* seg, SSizeT delta =
)
+
+Bool VG_(am_extend_into_adjacent_reservation)( NSegment* seg, SSizeT del=
ta )
{
Int segA, segR;
UInt prot;
@@ -2510,10 +2684,10 @@
|| nsegments[segR].smode !=3D SmLower
|| nsegments[segR].start !=3D nsegments[segA].end + 1
|| delta > (nsegments[segR].end - nsegments[segR].start + 1))
- return False;
+ return False;
=20
/* Extend the kernel's mapping. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
nsegments[segR].start, delta,
prot,
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,=20
@@ -2522,9 +2696,9 @@
if (sres.isError)
return False; /* kernel bug if this happens? */
if (sres.val !=3D nsegments[segR].start) {
- /* kernel bug if this happens? */
- do_munmap_NATIVE( sres.val, delta );
- return False;
+ /* kernel bug if this happens? */
+ do_munmap_NO_NOTIFY( sres.val, delta );
+ return False;
}
=20
/* Ok, success with the kernel. Update our structures. */
@@ -2544,10 +2718,10 @@
|| nsegments[segR].smode !=3D SmUpper
|| nsegments[segR].end + 1 !=3D nsegments[segA].start
|| delta > (nsegments[segR].end - nsegments[segR].start + 1))
- return False;
+ return False;
=20
/* Extend the kernel's mapping. */
- sres =3D VG_(aspacem_do_mmap_NO_NOTIFY)(=20
+ sres =3D VG_(am_do_mmap_NO_NOTIFY)(=20
nsegments[segA].start-delta, delta,
prot,
VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS,=20
@@ -2556,9 +2730,9 @@
if (sres.isError)
return False; /* kernel bug if this happens? */
if (sres.val !=3D nsegments[segA].start-delta) {
- /* kernel bug if this happens? */
- do_munmap_NATIVE( sres.val, delta );
- return False;
+ /* kernel bug if this happens? */
+ do_munmap_NO_NOTIFY( sres.val, delta );
+ return False;
}
=20
/* Ok, success with the kernel. Update our structures. */
@@ -2571,113 +2745,6 @@
return True;
}
=20
-
-void=20
-VG_(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;
- aspacem_assert(len > 0);
- aspacem_assert(VG_IS_PAGE_ALIGNED(a));
- aspacem_assert(VG_IS_PAGE_ALIGNED(len));
- init_nsegment( &seg );
- seg.kind =3D (flags & VKI_MAP_ANONYMOUS) ? SkAnon : SkFile;
- seg.isClient =3D True;
- seg.start =3D a;
- seg.end =3D a + len - 1;
- seg.offset =3D offset;
- seg.hasR =3D toBool(prot & VKI_PROT_READ);
- seg.hasW =3D toBool(prot & VKI_PROT_WRITE);
- seg.hasX =3D toBool(prot & VKI_PROT_EXEC);
- /* TODO: what about seg.hasT ? */
- if (get_inode_for_fd(fd, &dev, &ino)) {
- seg.dev =3D dev;
- seg.ino =3D ino;
- }
- if (get_name_for_fd(fd, buf, VKI_PATH_MAX)) {
- seg.fnIdx =3D allocate_segname( buf );
- }
- add_segment( &seg );
-}
-
-
-void VG_(notify_client_mprotect)( Addr start, SizeT len, UInt prot )
-{
- Int iLo, iHi;
-
- if (len =3D=3D 0)
- return;
-
- iLo =3D find_nsegment_idx(start);
- iHi =3D find_nsegment_idx(start + len - 1);
-
- if (iLo =3D=3D iHi=20
- && nsegments[iLo].start =3D=3D start=20
- && nsegments[iLo].end+1 =3D=3D start+len
- && (nsegments[iLo].kind =3D=3D SkFile || nsegments[iLo].kind =3D=3D=
SkAnon)) {
- nsegments[iLo].hasR =3D toBool(prot & VKI_PROT_READ);
- nsegments[iLo].hasW =3D toBool(prot & VKI_PROT_WRITE);
- nsegments[iLo].hasX =3D toBool(prot & VKI_PROT_EXEC);
- return;
- }
-
- /* FIXME: unhandled general case */
- aspacem_barf("notify_mprotect general case");
-}
-
-
-void VG_(notify_client_munmap)( Addr start, SizeT len )
-{
- NSegment seg;
-
- if (len =3D=3D 0)
- return;
-
- init_nsegment( &seg );
- seg.kind =3D SkFree;
- seg.start =3D start;
- seg.end =3D start + len - 1;
- add_segment( &seg );
-}
-
-
-/* Test if a piece of memory is addressable by the client with at
- least the "prot" protection permissions by examining the underlying
- segments.
-*/
-Bool VG_(aspacem_is_valid_for_client)( Addr start, SizeT len, UInt prot =
)
-{
- Int i, iLo, iHi;
- Bool needR, needW, needX;
-
- if (len =3D=3D 0)
- return True; /* somewhat dubious case */
- if (start + len < start)
- return False; /* reject wraparounds */
-
- needR =3D toBool(prot & VKI_PROT_READ);
- needW =3D toBool(prot & VKI_PROT_WRITE);
- needX =3D toBool(prot & VKI_PROT_EXEC);
-
- 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].isClient
- && (nsegments[i].kind =3D=3D SkFile || nsegments[i].kind =3D=3D=
SkAnon)
- && (needR ? nsegments[i].hasR : True)
- && (needW ? nsegments[i].hasW : True)
- && (needX ? nsegments[i].hasX : True)) {
- /* ok */
- } else {
- return False;
- }
- }
- return True;
-}
-
-
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
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-13 11:13:43 UTC (rev 4636=
)
+++ branches/ASPACEM/coregrind/m_main.c 2005-09-13 11:52:09 UTC (rev 4637=
)
@@ -607,7 +607,7 @@
=20
/* Create a shrinkable reservation followed by an anonymous
segment. Together these constitute a growdown stack. */
- Bool ok =3D VG_(create_reservation)(
+ Bool ok =3D VG_(am_create_reservation)(
resvn_start,
resvn_size,
SmUpper,=20
@@ -615,8 +615,8 @@
);
vg_assert(ok);
/* allocate a stack - mmap enough space for the stack */
- res =3D VG_(mmap_anon_fixed_client)(
- (void*)anon_start,
+ res =3D VG_(am_mmap_anon_fixed_client)(
+ anon_start,
anon_size,
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
);
@@ -779,10 +779,16 @@
vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
=20
- ok =3D VG_(create_reservation)( resvn_start, resvn_size, SmLower, ano=
n_size );
+ ok =3D VG_(am_create_reservation)(=20
+ resvn_start,=20
+ resvn_size,=20
+ SmLower,=20
+ anon_size
+ );
vg_assert(ok);
- sres =3D VG_(mmap_anon_fixed_client)(=20
- (void*)anon_start, anon_size,=20
+ sres =3D VG_(am_mmap_anon_fixed_client)(=20
+ anon_start,=20
+ anon_size,=20
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC=20
);
vg_assert(!sres.isError);
@@ -2172,7 +2178,7 @@
// p: logging, plausible-stack
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Starting the address space manager\n");
- clstack_top =3D VG_(new_aspacem_start)( sp_at_startup_new );
+ clstack_top =3D VG_(am_startup)( sp_at_startup_new );
VG_(debugLog)(1, "main", "Address space manager is running\n");
=20
//--------------------------------------------------------------
@@ -2559,7 +2565,7 @@
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "\n");
VG_(debugLog)(1, "main", "\n");
- VG_(show_nsegments)(1,"Memory layout at client startup");
+ VG_(am_show_nsegments)(1,"Memory layout at client startup");
VG_(debugLog)(1, "main", "\n");
VG_(debugLog)(1, "main", "\n");
=20
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-13 11:13:43 UTC (re=
v 4636)
+++ branches/ASPACEM/coregrind/m_mallocfree.c 2005-09-13 11:52:09 UTC (re=
v 4637)
@@ -481,7 +481,7 @@
void VG_(out_of_memory_NORETURN) ( HChar* who, SizeT szB )
{
static Bool alreadyCrashing =3D False;
- ULong tot_alloc =3D VG_(aspacem_get_anonsize_total)();
+ ULong tot_alloc =3D VG_(am_get_anonsize_total)();
if (!alreadyCrashing) {
alreadyCrashing =3D True;
VG_(printf)("\n"
@@ -537,7 +537,7 @@
return 0;
} else {
// non-client allocation -- aborts if it fails
- sres =3D VG_(map_anon_float_valgrind)( cszB );
+ sres =3D VG_(am_mmap_anon_float_valgrind)( cszB );
if (sres.isError) {
VG_(out_of_memory_NORETURN)("newSuperblock", cszB);
/* NOTREACHED */
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-13 11:13:43 UTC (rev 4=
636)
+++ branches/ASPACEM/coregrind/m_signals.c 2005-09-13 11:52:09 UTC (rev 4=
637)
@@ -1705,8 +1705,9 @@
SizeT udelta;
=20
/* Find the next Segment above addr */
- NSegment* seg =3D VG_(find_nsegment)(addr);
- NSegment* seg_next =3D seg ? VG_(next_nsegment)( seg, True/*fwds*/ ) =
: NULL;
+...
[truncated message content] |