|
From: <sv...@va...> - 2005-09-19 23:25:30
|
Author: sewardj
Date: 2005-09-20 00:25:26 +0100 (Tue, 20 Sep 2005)
New Revision: 4686
Log:
Delete the old address space manager and generally start tidying up.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_main.c
branches/ASPACEM/coregrind/m_stacktrace.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/pub_core_mallocfree.h
branches/ASPACEM/helgrind/hg_main.c
branches/ASPACEM/include/pub_tool_aspacemgr.h
branches/ASPACEM/include/pub_tool_libcmman.h
branches/ASPACEM/include/pub_tool_mallocfree.h
branches/ASPACEM/massif/ms_main.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 22:32:5=
1 UTC (rev 4685)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-19 23:25:2=
6 UTC (rev 4686)
@@ -49,11 +49,6 @@
static void aspacem_barf ( HChar* what );
=20
=20
-/* Define to debug the memory-leak-detector. */
-/* #define VG_DEBUG_LEAKCHECK */
-
-static const Bool mem_debug =3D False;
-
/*--------------------------------------------------------------*/
/*--- Basic globals about the address space. ---*/
/*--------------------------------------------------------------*/
@@ -78,50 +73,7 @@
// the VG_(*_end) vars name the byte one past the end of the section.
Addr VG_(valgrind_last);
=20
-/*--------------------------------------------------------------*/
-/*--- The raw mman syscalls ---*/
-/*--------------------------------------------------------------*/
=20
-SysRes VG_(mmap_native)(void *start, SizeT length, UInt prot, UInt flags=
,
- UInt fd, OffT offset)
-{
- SysRes res;
-aspacem_barf("mmap_native");
-#if defined(VGP_x86_linux)
- {=20
- UWord args[6];
- args[0] =3D (UWord)start;
- args[1] =3D length;
- args[2] =3D prot;
- args[3] =3D flags;
- args[4] =3D fd;
- args[5] =3D offset;
- res =3D VG_(do_syscall1)(__NR_mmap, (UWord)args );
- }
-#elif defined(VGP_amd64_linux)
- res =3D VG_(do_syscall6)(__NR_mmap, (UWord)start, length,=20
- prot, flags, fd, offset);
-#elif defined(VGP_ppc32_linux)
- res =3D VG_(do_syscall6)(__NR_mmap, (UWord)(start), (length),
- prot, flags, fd, offset);
-#else
-# error Unknown platform
-#endif
- return res;
-}
-
-SysRes VG_(munmap_native)(void *start, SizeT length)
-{
-aspacem_barf("munmap_native");
- return VG_(do_syscall2)(__NR_munmap, (UWord)start, length );
-}
-
-SysRes VG_(mprotect_native)( void *start, SizeT length, UInt prot )
-{
-aspacem_barf("mprotect_native");
- return VG_(do_syscall3)(__NR_mprotect, (UWord)start, length, prot );
-}
-
/*--------------------------------------------------------------*/
/*--- A simple, self-contained ordered array of segments. ---*/
/*--------------------------------------------------------------*/
@@ -138,15 +90,6 @@
=20
/* ------ STATE for the address-space manager ------ */
=20
-/* Array [0 .. segments_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 Segment segments[VG_N_SEGMENTS];
-static Int segments_used =3D 0;
-
typedef
struct {
Bool inUse;
@@ -227,1124 +170,6 @@
}
=20
=20
-/* Returns -1 if 'a' denotes an address prior to seg, 1 if it denotes
- an address after it, and 0 if it denotes an address covered by
- seg.=20
-*/
-static inline Int compare_addr_with_seg ( Addr a, Segment* seg )
-{
- if (a < seg->addr)=20
- return -1;
- if (a >=3D seg->addr + seg->len)=20
- return 1;
- return 0;
-}
-
-
-/* Find the (index of the) segment that contains 'a', or -1 if
- none.=20
-*/
-static Int find_segment ( Addr a )
-{
- Int i;
- for (i =3D 0; i < segments_used; i++) {
- if (compare_addr_with_seg(a, &segments[i]) =3D=3D 0)
- return i;
- }
- return -1;
-}
-
-
-/* Assumes that 'a' is not in any segment. Finds the index of the
- lowest-addressed segment above 'a', or -1 if none. Passing 'a'
- which is in fact in a segment is a checked error.=20
-*/
-static Int find_segment_above_unmapped ( Addr a )
-{
- Int i, r;
- for (i =3D 0; i < segments_used; i++) {
- r =3D compare_addr_with_seg(a, &segments[i]);
- vg_assert(r !=3D 0); /* 'a' should not be in any segment. */
- if (r =3D=3D 1)
- continue;
- vg_assert(r =3D=3D -1);
- break;
- }
-
- if (i =3D=3D segments_used)
- return -1; /* not found */
- else
- return i;
-}
-
-
-/* Assumes that 'a' is in some segment. Finds the next segment along,
- or NULL if none. Passing 'a' which is in fact not in a segment is
- a checked error.
-*/
-static Int find_segment_above_mapped ( Addr a )
-{
- Int i, r;
- for (i =3D 0; i < segments_used; i++) {
- r =3D compare_addr_with_seg(a, &segments[i]);
- if (r =3D=3D 1)
- continue; /* not yet there */
- if (r =3D=3D 0)
- break; /* found it */
- vg_assert(0);
- /* we shouldn't get here -- r =3D=3D -1 and so it means we went pa=
st=20
- 'a' without seeing it -- it is therefore unmapped. */
- /*NOTREACHED*/
- }
-
- vg_assert(i < segments_used);
- if (i =3D=3D segments_used-1)
- return -1; /* not found */
- else
- return i+1;
-}
-
-
-/* Shift segments[i .. segments_used-1] up by one. */
-static void make_space_at ( Int i )
-{
- Int j;
- vg_assert(i >=3D 0 && i <=3D segments_used);
- vg_assert(segments_used >=3D 0);
- if (segments_used+1 =3D=3D VG_N_SEGMENTS) {
- VG_(printf)(
- "coregrind/m_aspacemgr/aspacemgr.c:\n"
- " VG_N_SEGMENTS is too small: "
- "increase it and rebuild Valgrind.\n"
- );
- VG_(printf)(
- "coregrind/m_aspacemgr/aspacemgr.c:\n"
- " giving up now.\n\n"
- );
- VG_(exit)(0);
- }
- vg_assert(segments_used+1 < VG_N_SEGMENTS);
- for (j =3D segments_used; j > i; j--)
- segments[j] =3D segments[j-1];
- segments_used++;
-}
-
-// Forward declaration
-static void dealloc_seg_memory(Segment *s);
-
-/* Shift segments [i+1 .. segments_used-1] down by one, and decrement
- segments_used.=20
-*/
-static void delete_segment_at ( Int i )
-{
- Int j;
- vg_assert(i >=3D 0 && i < segments_used);
- dealloc_seg_memory(&segments[i]);
- for (j =3D i+1; j < segments_used; j++) {
- segments[j-1] =3D segments[j];
- }
- segments_used--;
- vg_assert(segments_used >=3D 0 && segments_used < VG_N_SEGMENTS);
-}
-
-
-/* Fill the i'th record all with zeroes. */
-static void zeroise_segment ( Int i )
-{
- vg_assert(i >=3D 0 && i < segments_used);
- segments[i].prot =3D 0;
- segments[i].flags =3D 0;
- segments[i].addr =3D 0;
- segments[i].len =3D 0;
- segments[i].offset =3D 0;
- segments[i].filename =3D NULL;
- segments[i].fnIdx =3D -1;
- segments[i].dev =3D 0;
- segments[i].ino =3D 0;
- segments[i].seginfo =3D NULL;
-}
-
-
-/* Create a segment to contain 'a', and return its index. Or -1 if
- this failed because some other segment already contains 'a'. If
- successful, fill in the segment's .addr field with 'a' but leave
- all other fields alone.=20
-*/
-static Int create_segment ( Addr a )
-{
- Int i, r;
- for (i =3D 0; i < segments_used; i++) {
- r =3D compare_addr_with_seg( a, &segments[i] );
- if (r =3D=3D 1)
- continue; /* seg[i] precedes a */
- if (r =3D=3D 0)
- return -1; /* seg[i] contains a. Give up */
- vg_assert(r =3D=3D -1);
- break;
- }
- /* a precedes seg[i]. Shift segs at i and above up one, and use
- this slot. */
- make_space_at(i);
- zeroise_segment(i);
- segments[i].addr =3D a;
- return i;
-}
-
-
-/* Print out the segment array (debugging only!). Note, this calls
- VG_(printf), and I'm not 100% clear that that wouldn't require
- dynamic memory allocation and hence more segments to be allocated.
-*/
-static void show_segments ( HChar* who )
-{
- Int i;
- VG_(printf)("<<< 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_(printf)("(%2d) %s\n", i, segnames[i].fname);
- }
- for (i =3D 0; i < segments_used; i++) {
- VG_(printf)(
- "%3d: %08p-%08p %7llu pr=3D0x%x fl=3D0x%04x d=3D0x%03x i=3D%-7d=
o=3D%-7lld (%d)\n",
- i,
- segments[i].addr, segments[i].addr + segments[i].len,
- (ULong)segments[i].len, segments[i].prot,=20
- segments[i].flags, segments[i].dev, segments[i].ino,=20
- (Long)segments[i].offset,=20
- segments[i].fnIdx);
- }
- VG_(printf)(">>>\n");
-}
-
-
-/* Find the segment containing 'a' and split it into two pieces at
- 'a'. Does nothing if no segment contains 'a', or if the split
- would cause either of the pieces to have zero size.
-
- If 'a' is not found, or if no splitting happens, -1 is returned.
-
- If a value 'r' other than -1 is returned, this is the index of the
- higher-addressed segment resulting from the split, and the index of
- the lower-addressed segment is r-1.
-*/
-static Int split_segment ( Addr a )
-{
- Int r;
- HWord delta;
- vg_assert(VG_IS_PAGE_ALIGNED(a));
- r =3D find_segment(a);
- if (r =3D=3D -1)
- /* not found */
- return -1;
- if (segments[r].addr =3D=3D a)
- /* segment starts at 'a', so splitting it would create a
- zero-sized segment */
- return -1;
-
- /* copy original; make adjustments. */
- vg_assert(a > segments[r].addr);
- delta =3D a - segments[r].addr;
- make_space_at(r);
- =20
- segments[r] =3D segments[r+1];
- segments[r].len =3D delta;
- if (segments[r].seginfo)
- VG_(seginfo_incref)(segments[r].seginfo);
- =20
- segments[r+1].len -=3D delta;
- segments[r+1].addr +=3D delta;
- segments[r+1].offset +=3D delta;
- return r+1;
-}
-
-
-/* Return true if two segments are adjacent and mergable (s1 is
- assumed to have a lower ->addr than s2) */
-static inline Bool segments_are_mergeable(Segment *s1, Segment *s2)
-{
- if (s1->addr+s1->len !=3D s2->addr)
- return False;
-
- if (s1->flags !=3D s2->flags)
- return False;
-
- if (s1->prot !=3D s2->prot)
- return False;
-
- if (s1->seginfo !=3D s2->seginfo)
- return False;
-
- if (s1->flags & SF_FILE){
- if ((s1->offset + s1->len) !=3D s2->offset)
- return False;
- if (s1->dev !=3D s2->dev)
- return False;
- if (s1->ino !=3D s2->ino)
- return False;
- if (s1->fnIdx !=3D s2->fnIdx)
- return False;
- }
- =20
- return True;
-}
-
-
-/* Clean up and sanity check the segment array:
- - check segments are in ascending order
- - check segments do not overlap
- - check no segment has zero size
- - merge adjacent where possible
- - perform checks on the filename table, and reclaim dead entries
-*/
-static void preen_segments ( void )
-{
- Int i, j, rd, wr;
- Segment *s, *s1;
- aspacem_barf("preen_segments");
- vg_assert(segments_used >=3D 0 && segments_used < VG_N_SEGMENTS);
- vg_assert(segnames_used >=3D 0 && segnames_used < VG_N_SEGNAMES);
-
- if (0) show_segments("before preen");
-
- /* clear string table mark bits */
- for (i =3D 0; i < segnames_used; i++)
- segnames[i].mark =3D False;
-
- /* check for non-zero size, and set mark bits for any used strings */
- for (i =3D 0; i < segments_used; i++) {
- vg_assert(segments[i].len > 0);
- j =3D segments[i].fnIdx;
- vg_assert(j >=3D -1 && j < segnames_used);
- if (j >=3D 0) {
- vg_assert(segnames[j].inUse);
- segnames[j].mark =3D True;
- }
- }
-
- /* check ascendingness and non-overlap */
- for (i =3D 0; i < segments_used-1; i++) {
- s =3D &segments[i];
- s1 =3D &segments[i+1];
- vg_assert(s->addr < s1->addr);
- vg_assert(s->addr + s->len <=3D s1->addr);
- }
-
- /* merge */
- if (segments_used < 1)
- return;
-
- wr =3D 1;
- for (rd =3D 1; rd < segments_used; rd++) {
- s =3D &segments[wr-1];
- s1 =3D &segments[rd];
- if (segments_are_mergeable(s,s1)) {
- if (0)
- VG_(printf)("merge %p-%p with %p-%p\n",
- s->addr, s->addr+s->len,
- s1->addr, s1->addr+s1->len);
- s->len +=3D s1->len;
-
- vg_assert(s->seginfo =3D=3D s1->seginfo);
- dealloc_seg_memory(s1);
- =20
- continue;
- }
- if (wr < rd)
- segments[wr] =3D segments[rd];
- wr++;
- }
- vg_assert(wr >=3D 0 && wr <=3D segments_used);
- segments_used =3D wr;
-
- /* Free up any strings which are no longer referenced. */
- for (i =3D 0; i < segnames_used; i++) {
- if (segnames[i].mark =3D=3D False) {
- segnames[i].inUse =3D False;
- segnames[i].fname[0] =3D 0;
- }
- }
-
- if (0) show_segments("after preen");
-}
-
-
-/*--------------------------------------------------------------*/
-/*--- Maintain an ordered list of all the client's mappings ---*/
-/*--------------------------------------------------------------*/
-
-Bool VG_(seg_contains)(const Segment *s, Addr p, SizeT len)
-{
- Addr se =3D s->addr+s->len;
- Addr pe =3D p+len;
-aspacem_barf("seg_contains");
- vg_assert(pe >=3D p);
-
- return (p >=3D s->addr && pe <=3D se);
-}
-
-Bool VG_(seg_overlaps)(const Segment *s, Addr p, SizeT len)
-{
- Addr se =3D s->addr+s->len;
- Addr pe =3D p+len;
-aspacem_barf("seg_overlaps");
- vg_assert(pe >=3D p);
-
- return (p < se && pe > s->addr);
-}
-
-/* When freeing a Segment, also clean up every one else's ideas of
- what was going on in that range of memory */
-static void dealloc_seg_memory(Segment *s)
-{
- if (s->seginfo !=3D NULL) {
- VG_(seginfo_decref)(s->seginfo, s->addr);
- s->seginfo =3D NULL;
- }
-}
-
-/* Get rid of any translations arising from s. */
-/* Note, this is not really the job of the low level memory manager.
- When it comes time to rewrite this subsystem, clean this up. */
-static void dump_translations_from ( Segment* s )
-{
- if (s->flags & SF_CODE) {
- VG_(discard_translations)(s->addr, s->len);
- if (0)
- VG_(printf)("dumping translations in %p .. %p\n",
- s->addr, s->addr+s->len);
- }
-}
-
-
-/* This unmaps all the segments in the range [addr, addr+len); any
- partial mappings at the ends are truncated. */
-void VG_(unmap_range)(Addr addr, SizeT len)
-{
- const Bool debug =3D False || mem_debug;
- Segment* s;
- Addr end, s_end;
- Int i;
- Bool deleted;
-aspacem_barf("unmap_range");
-
- if (len =3D=3D 0)
- return;
-
- len =3D VG_PGROUNDUP(len);
-
- if (debug)
- VG_(printf)("unmap_range(%p, %llu)\n", addr, (ULong)len);
- if (0) show_segments("unmap_range(BEFORE)");
- end =3D addr+len;
-
- /* Everything must be page-aligned */
- vg_assert(VG_IS_PAGE_ALIGNED(addr));
- vg_assert(VG_IS_PAGE_ALIGNED(len));
-
- for (i =3D 0; i < segments_used; i++) {
-
- /* do not delete .. even though it looks stupid */
- vg_assert(i >=3D 0);
-
- deleted =3D False;
- s =3D &segments[i];
- s_end =3D s->addr + s->len;
-
- if (0 && debug)
- VG_(printf)("unmap: addr=3D%p-%p s=3D%p ->addr=3D%p-%p len=3D%d\n",
- addr, end, s, s->addr, s_end, s->len);
-
- if (!VG_(seg_overlaps)(s, addr, len)) {
- if (0 && debug)
- VG_(printf)(" (no overlap)\n");
- continue;
- }
-
- /* 4 cases: */
- if (addr > s->addr &&
- addr < s_end &&
- end >=3D s_end) {
- /* this segment's tail is truncated by [addr, addr+len)
- -> truncate tail
- */
- dump_translations_from(s);
- s->len =3D addr - s->addr;
-
- if (debug)
- VG_(printf)(" case 1: s->len=3D%lu\n", s->len);
- } else if (addr <=3D s->addr && end > s->addr && end < s_end) {
- /* this segment's head is truncated by [addr, addr+len)
- -> truncate head
- */
- Word delta =3D end - s->addr;
-
- if (debug)
- VG_(printf)(" case 2: s->addr=3D%p s->len=3D%lu delta=3D%d\n",=20
- s->addr, s->len, delta);
-
- dump_translations_from(s);
- s->addr +=3D delta;
- s->offset +=3D delta;
- s->len -=3D delta;
-
- vg_assert(s->len !=3D 0);
- } else if (addr <=3D s->addr && end >=3D s_end) {
- /* this segment is completely contained within [addr, addr+len)
- -> delete segment
- */
- dump_translations_from(s);
- delete_segment_at(i);
- deleted =3D True;
-
- if (debug)
- VG_(printf)(" case 3: seg %d deleted\n", i);
- } else if (addr > s->addr && end < s_end) {
- /* [addr, addr+len) is contained within a single segment
- -> split segment into 3, delete middle portion
- */
- Int i_middle;
- dump_translations_from(s);
- i_middle =3D split_segment(addr);
- vg_assert(i_middle !=3D -1);
- (void)split_segment(addr+len);
- vg_assert(segments[i_middle].addr =3D=3D addr);
- delete_segment_at(i_middle);
- deleted =3D True;
-
- if (debug)
- VG_(printf)(" case 4: subrange %p-%p deleted\n",
- addr, addr+len);
- }
-
- /* If we deleted this segment (or any above), those above will
- have been moved down to fill in the hole in the segment
- array. In order that we don't miss them, we have to
- re-consider this slot number; hence the i--. */
- if (deleted)
- i--;
- }
- preen_segments();
- if (0) show_segments("unmap_range(AFTER)");
-}
-
-
-/* Add a binding of [addr,addr+len) to
- (prot,flags,dev,ino,off,filename) in the segment array.
- Delete/truncate any previous mapping(s) covering that range.
-*/
-void=20
-VG_(map_file_segment)( Addr addr, SizeT len,=20
- UInt prot, UInt flags,=20
- UInt dev, UInt ino, ULong off,=20
- const Char *filename)
-{
- const Bool debug =3D False || mem_debug;
- Segment* s;
- Int idx;
- HChar* stage2_suffix1 =3D "lib/valgrind/stage2";
- HChar* stage2_suffix2 =3D "coregrind/stage2";
- Bool is_stage2 =3D False;
-aspacem_barf("map_file_segment");
- =20
- is_stage2 =3D is_stage2 || ( VG_(strstr)(filename, stage2_suffix1) !=3D=
NULL );
- is_stage2 =3D is_stage2 || ( VG_(strstr)(filename, stage2_suffix2) !=3D=
NULL );
-
- if (debug)
- VG_(printf)(
- "\n"
- "map_file_segment(addr=3D%p len=3D%lu prot=3D0x%x flags=3D0x%x\=
n"
- " dev=3D0x%4x ino=3D%d off=3D%ld\n"
- " filename=3D'%s')\n",
- addr, (ULong)len, prot, flags, dev, ino, off, filename);
-
- if (0) show_segments("before map_file_segment");
-
- /* Everything must be page-aligned */
- vg_assert(VG_IS_PAGE_ALIGNED(addr));
- len =3D VG_PGROUNDUP(len);
-
- /* Nuke/truncate any existing segment(s) covering [addr,addr+len) */
- VG_(unmap_range)(addr, len);
-
- /* and now install this one */
- idx =3D create_segment(addr);
- vg_assert(segments_used >=3D 0 && segments_used <=3D VG_N_SEGMENTS);
- vg_assert(idx !=3D -1);
- vg_assert(idx >=3D 0 && idx < segments_used);
-
- s =3D &segments[idx];
- vg_assert(s->addr =3D=3D addr);
- s->prot =3D prot;
- s->flags =3D flags;
- s->len =3D len;
- s->offset =3D off;
- s->fnIdx =3D filename=3D=3DNULL ? -1 : allocate_segname(filename);
- s->filename =3D s->fnIdx=3D=3D-1 ? NULL : &segnames[s->fnIdx].fname[0=
];
- s->dev =3D dev;
- s->ino =3D ino;
- s->seginfo =3D NULL;
-
- /* Clean up right now */
- preen_segments();
- if (0) show_segments("after map_file_segment");
-
- /* If this mapping is at the beginning of a file, isn't part of
- Valgrind, is at least readable and seems to contain an object
- file, then try reading symbols from it.
-
- Getting this heuristic right is critical. On x86-linux,
- objects are typically mapped twice:
-
- 1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.s=
o
- 1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.s=
o
-
- whereas ppc32-linux mysteriously does this:
-
- 118a6000-118ad000 r-xp 00000000 08:05 14209428 vgpreload_memcheck.=
so
- 118ad000-118b6000 ---p 00007000 08:05 14209428 vgpreload_memcheck.=
so
- 118b6000-118bd000 rwxp 00000000 08:05 14209428 vgpreload_memcheck.=
so
-
- The third mapping should not be considered to have executable code=
in.
- Therefore a test which works for both is: r and x and NOT w. Read=
ing
- symbols from the rwx segment -- which overlaps the r-x segment in =
the
- file -- causes the redirection mechanism to redirect to addresses =
in
- that third segment, which is wrong and causes crashes.
- */
- if (s->seginfo =3D=3D NULL
- && ( (addr+len < VG_(valgrind_base) || addr > VG_(valgrind_last))
- || is_stage2
- )
- && (flags & (SF_MMAP|SF_NOSYMS)) =3D=3D SF_MMAP
- ) {
- if (off =3D=3D 0
- && s->fnIdx !=3D -1
- /* r, x are set */
- && (prot & (VKI_PROT_READ|VKI_PROT_EXEC)) =3D=3D (VKI_PROT_READ=
|VKI_PROT_EXEC)
- /* w is clear */
- && (prot & VKI_PROT_WRITE) =3D=3D 0
- /* other checks .. */
- && len >=3D VKI_PAGE_SIZE
- && VG_(is_object_file)((void *)addr) ) {
- s->seginfo =3D VG_(read_seg_symbols)(s->addr, s->len, s->offset=
,
- s->filename);
- }
- else if (flags & SF_MMAP)=20
- {
- const SegInfo *si;
- =20
- /* Otherwise see if an existing SegInfo applies to this Segment=
*/
- for (si =3D VG_(next_seginfo)(NULL);
- si !=3D NULL;
- si =3D VG_(next_seginfo)(si))=20
- {
- if (VG_(seg_overlaps)(s, VG_(seginfo_start)(si),=20
- VG_(seginfo_size)(si)))
- {
- s->seginfo =3D (SegInfo *)si;
- VG_(seginfo_incref)((SegInfo *)si);
- }
- }
- }
- }
-
- /* clean up */
- preen_segments();
-}
-
-void VG_(map_fd_segment)(Addr addr, SizeT len, UInt prot, UInt flags,=20
- Int fd, ULong off, const Char *filename)
-{
- Char buf[VKI_PATH_MAX];
- struct vki_stat st;
-aspacem_barf("map_fd_segment");
-
- st.st_dev =3D 0;
- st.st_ino =3D 0;
-
- if (fd !=3D -1 && (flags & SF_FILE)) {
- vg_assert((off & (VKI_PAGE_SIZE-1)) =3D=3D 0);
-
- if (VG_(fstat)(fd, &st) < 0)
- flags &=3D ~SF_FILE;
- }
-
- if ((flags & SF_FILE) && filename =3D=3D NULL && fd !=3D -1)
- if (VG_(resolve_filename)(fd, buf, VKI_PATH_MAX))
- filename =3D buf;
-
- VG_(map_file_segment)(addr, len, prot, flags,=20
- st.st_dev, st.st_ino, off, filename);
-}
-
-void VG_(map_segment)(Addr addr, SizeT len, UInt prot, UInt flags)
-{
-aspacem_barf("map_segment");
- flags &=3D ~SF_FILE;
-
- VG_(map_file_segment)(addr, len, prot, flags, 0, 0, 0, 0);
-}
-
-/* set new protection flags on an address range */
-void VG_(mprotect_range)(Addr a, SizeT len, UInt prot)
-{
- Int r;
- const Bool debug =3D False || mem_debug;
-aspacem_barf("mprotect_range");
-
- if (debug)
- VG_(printf)("\nmprotect_range(%p, %lu, %x)\n", a, len, prot);
-
- if (0) show_segments( "mprotect_range(before)" );
-
- /* Everything must be page-aligned */
- vg_assert(VG_IS_PAGE_ALIGNED(a));
- len =3D VG_PGROUNDUP(len);
-
- split_segment(a);
- split_segment(a+len);
-
- r =3D find_segment(a);
- vg_assert(r !=3D -1);
- segments[r].prot =3D prot;
-
- preen_segments();
-
- if (0) show_segments( "mprotect_range(after)");
-}
-
-
-/* Try to find a map space for [addr,addr+len). If addr=3D=3D0, it mean=
s
- the caller is prepared to accept a space at any location; if not,
- we will try for addr, but fail if we can't get it. This mimics
- mmap fixed vs mmap not-fixed.
-*/
-Addr VG_(find_map_space)(Addr addr, SizeT len, Bool for_client)
-{
- const Bool debug =3D False || mem_debug;
-aspacem_barf("find_map_space");
-
- Addr ret;
- Addr addrOrig =3D addr;
- Addr limit =3D (for_client ? VG_(client_end)-1 : VG_(valgrind_last)=
);
- Addr base =3D (for_client ? VG_(client_mapbase) : VG_(valgrind_base)=
);
- Addr hole_start, hole_end, hstart_any, hstart_fixed, hstart_final;
- Int i, i_any, i_fixed, i_final;
- SizeT hole_len;
-
- Bool fixed;
-
- if (debug) {
- VG_(printf)("\n\n");
- VG_(printf)("find_map_space(%p, %llu, %d) ...\n",
- addr, (ULong)len, for_client);
- }
-
- if (0) show_segments("find_map_space: start");
-
- if (addr =3D=3D 0) {
- fixed =3D False;
- } else {
- fixed =3D True;
- /* leave space for redzone and still try to get the exact
- address asked for */
- addr -=3D VKI_PAGE_SIZE;
- }
-
- /* Everything must be page-aligned */
- vg_assert((addr & (VKI_PAGE_SIZE-1)) =3D=3D 0);
- len =3D VG_PGROUNDUP(len);
-
- len +=3D VKI_PAGE_SIZE * 2; /* leave redzone gaps before and after ma=
pping */
-
- /* Scan the segment list, looking for a hole which satisfies the
- requirements. At each point i we ask the question "can we use
- the hole in between segments[i-1] and segments[i] ?" */
- i_any =3D i_fixed =3D -1;
- hstart_any =3D hstart_fixed =3D 0;
-
- hole_start =3D hole_end =3D 0;
-
- /* Iterate over all possible holes, generating them into
- hole_start/hole_end. Filter out invalid ones. Then see if any
- are usable; if so set i_fixed/i_any and hstart_fixed/hstart_any. =20
- */
- for (i =3D 0; i <=3D/*yes,really*/ segments_used; i++) {
- if (i =3D=3D 0) {
- hole_start =3D 0;
- hole_end =3D segments[0].addr-1;
- }=20
- else {
- vg_assert(segments_used > 0);
- if (i =3D=3D segments_used) {
- hole_start =3D segments[i-1].addr + segments[i-1].len;
- hole_end =3D ~(Addr)0;
- } else {
- hole_start =3D segments[i-1].addr + segments[i-1].len;
- hole_end =3D segments[i].addr - 1;
- }
- }
-
- vg_assert(hole_start <=3D hole_end || hole_start =3D=3D hole_end+1=
);
-
- /* ignore zero-sized holes */
- if (hole_start =3D=3D hole_end+1)
- continue;
-
- vg_assert(VG_IS_PAGE_ALIGNED(hole_start));
- vg_assert(VG_IS_PAGE_ALIGNED(hole_end+1));
-
- /* ignore holes which fall outside the allowable area */
- if (!(hole_start >=3D base && hole_end <=3D limit))
- continue;
-
- vg_assert(hole_end > hole_start);
- hole_len =3D hole_end - hole_start + 1;
- vg_assert(VG_IS_PAGE_ALIGNED(hole_len));
-
- if (hole_len >=3D len && i_any =3D=3D -1) {
- /* It will at least fit in this hole. */
- i_any =3D i;
- hstart_any =3D hole_start;
- }
-
- if (fixed && hole_start <=3D addr=20
- && hole_start+hole_len >=3D addr+len) {
- /* We were asked for a fixed mapping, and this hole works.
- Bag it -- and stop searching as further searching is
- pointless. */
- i_fixed =3D i;
- hstart_fixed =3D addr;
- break;
- }
- }
-
- /* Summarise the final decision into i_final/hstart_final. */
- i_final =3D -1;
- hstart_final =3D 0;
-
- if (fixed) {
- i_final =3D i_fixed;
- hstart_final =3D hstart_fixed + VKI_PAGE_SIZE; /* skip leading re=
dzone */
- } else {
- i_final =3D i_any;
- hstart_final =3D hstart_any;
- }
-
-
- if (i_final !=3D -1)
- ret =3D hstart_final;
- else
- ret =3D 0; /* not found */
-
- if (debug)
- VG_(printf)("find_map_space(%p, %llu, %d) -> %p\n\n",
- addr, (ULong)len, for_client, ret);
-
- if (fixed) {
- vg_assert(ret =3D=3D 0 || ret =3D=3D addrOrig);
- }
-
- return ret;
-}
-
-
-/* Pad the entire process address space, from "start"
- to VG_(valgrind_last) by creating an anonymous and inaccessible
- mapping over any part of the address space which is not covered
- by an entry in the segment list.
-
- This is designed for use around system calls which allocate
- memory in the process address space without providing a way to
- control its location such as io_setup. By choosing a suitable
- address with VG_(find_map_space) and then adding a segment for
- it and padding the address space valgrind can ensure that the
- kernel has no choice but to put the memory where we want it. */
-void VG_(pad_address_space)(Addr start)
-{
- Addr addr =3D (start =3D=3D 0) ? VG_(client_base) : start;
- SysRes ret;
-aspacem_barf("pad_address_space");
-
- Int i =3D 0;
- Segment* s =3D i >=3D segments_used ? NULL : &segments[i];
- =20
- while (s && addr <=3D VG_(valgrind_last)) {
- if (addr < s->addr) {
- ret =3D VG_(mmap_native)((void*)addr, s->addr - addr, 0,
- VKI_MAP_FIXED | VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS=
,
- -1, 0);
- vg_assert(!ret.isError);
- }
- addr =3D s->addr + s->len;
- i++;
- s =3D i >=3D segments_used ? NULL : &segments[i];
- }
-
- if (addr <=3D VG_(valgrind_last)) {
- ret =3D VG_(mmap_native)((void*)addr, VG_(valgrind_last) - addr + =
1, 0,
- VKI_MAP_FIXED | VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS,
- -1, 0);
- vg_assert(!ret.isError);
- }
-}
-
-/* Remove the address space padding added by VG_(pad_address_space)
- by removing any mappings that it created. */
-void VG_(unpad_address_space)(Addr start)
-{
- Addr addr =3D (start =3D=3D 0) ? VG_(client_base) : start;
- SysRes ret;
-
- Int i =3D 0;
- Segment* s =3D i >=3D segments_used ? NULL : &segments[i];
-aspacem_barf("unpad_address_space");
-
- while (s && addr <=3D VG_(valgrind_last)) {
- if (addr < s->addr) {
- //ret =3D VG_(do_syscall2)(__NR_munmap, addr, s->addr - addr);
- ret =3D VG_(do_syscall2)(__NR_munmap, addr, s->addr - addr);
- }
- addr =3D s->addr + s->len;
- i++;
- s =3D i >=3D segments_used ? NULL : &segments[i];
- }
-
- if (addr <=3D VG_(valgrind_last)) {
- ret =3D VG_(do_syscall2)(__NR_munmap, addr,=20
- (VG_(valgrind_last) - addr) + 1);
- }
-}
-
-/* Find the segment holding 'a', or NULL if none. */
-Segment *VG_(find_segment)(Addr a)
-{
- Int r =3D find_segment(a);
-aspacem_barf("find_segment");
-
- if (0) show_segments("find_segment");
- if (r =3D=3D -1) return NULL;
- return &segments[r];
-}
-
-/* Assumes that 'a' is not in any segment. Finds the lowest-addressed
- segment above 'a', or NULL if none. Passing 'a' which is in fact in
- a segment is a checked error.
-*/
-Segment *VG_(find_segment_above_unmapped)(Addr a)
-{
- Int r =3D find_segment_above_unmapped(a);
-aspacem_barf("find_segment_above_unmapped");
- if (0) show_segments("find_segment_above_unmapped");
- if (r =3D=3D -1) return NULL;
- return &segments[r];
-}
-
-/* Assumes that 'a' is in some segment. Finds the next segment along,
- or NULL if none. Passing 'a' which is in fact not in a segment is
- a checked error.
-*/
-Segment *VG_(find_segment_above_mapped)(Addr a)
-{
- Int r =3D find_segment_above_mapped(a);
-aspacem_barf("find_segment_above_mapped");
- if (0) show_segments("find_segment_above_mapped");
- if (r =3D=3D -1) return NULL;
- return &segments[r];
-}
-
-
-/*=20
- Test if a piece of memory is addressable with at least the "prot"
- protection permissions by examining the underlying segments.
-
- Really this is a very stupid algorithm and we could do much
- better by iterating through the segment array instead of through
- the address space.
- */
-Bool VG_(is_addressable)(Addr p, SizeT size, UInt prot)
-{
- Segment *seg;
-aspacem_barf("is_addressable");
-
- if ((p + size) < p)
- return False; /* reject wraparounds */
- if (size =3D=3D 0)
- return True; /* isn't this a bit of a strange case? */
-
- p =3D VG_PGROUNDDN(p);
- size =3D VG_PGROUNDUP(size);
- vg_assert(VG_IS_PAGE_ALIGNED(p));
- vg_assert(VG_IS_PAGE_ALIGNED(size));
-
- for (; size > 0; size -=3D VKI_PAGE_SIZE) {
- seg =3D VG_(find_segment)(p);
- if (!seg)
- return False;
- if ((seg->prot & prot) !=3D prot)
- return False;
- p +=3D VKI_PAGE_SIZE;
- }
-
- return True;
-}
-
-
-/*--------------------------------------------------------------------*/
-/*--- Random function that doesn't really belong here ---*/
-/*--------------------------------------------------------------------*/
-
-/* We'll call any RW mmaped memory segment, within the client address
- range, which isn't SF_CORE, a root.=20
-*/
-void VG_(find_root_memory)(void (*add_rootrange)(Addr a, SizeT sz))
-{
- Int i;
- UInt flags;
- Segment *s;
-aspacem_barf("find_root_memory");
-
- for (i =3D 0; i < segments_used; i++) {
- s =3D &segments[i];
- flags =3D s->flags & (SF_SHARED|SF_MMAP|SF_VALGRIND|SF_CORE|SF_STA=
CK);
- if (flags !=3D SF_MMAP && flags !=3D SF_STACK && flags !=3D (SF_MM=
AP|SF_STACK))
- continue;
- if ((s->prot & (VKI_PROT_READ|VKI_PROT_WRITE))=20
- !=3D (VKI_PROT_READ|VKI_PROT_WRITE))
- continue;
- if (!VG_(is_client_addr)(s->addr) ||
- !VG_(is_client_addr)(s->addr+s->len-1))
- continue;
-
- (*add_rootrange)(s->addr, s->len);
- }
-}
-
-
-/*--------------------------------------------------------------------*/
-/*--- Querying memory layout ---*/
-/*--------------------------------------------------------------------*/
-
-Bool VG_(is_client_addr)(Addr a)
-{
-aspacem_barf("is_client_addr");
- return a >=3D VG_(client_base) && a < VG_(client_end);
-}
-
-Bool VG_(is_shadow_addr)(Addr a)
-{
-aspacem_barf("is_shadow_addr");
- return a >=3D VG_(shadow_base) && a < VG_(shadow_end);
-}
-
-
-/*--------------------------------------------------------------------*/
-/*--- Handling shadow memory ---*/
-/*--------------------------------------------------------------------*/
-
-void *VG_(shadow_alloc)(UInt size)
-{
- static Addr shadow_alloc =3D 0;
- Addr try_here;
- SysRes r;
-aspacem_barf("shadow_alloc");
-
- if (0) show_segments("shadow_alloc(before)");
-
- vg_assert(VG_(needs).shadow_memory);
-
- size =3D VG_PGROUNDUP(size);
-
- if (shadow_alloc =3D=3D 0)
- shadow_alloc =3D VG_(shadow_base);
-
- if (shadow_alloc >=3D VG_(shadow_end))
- goto failed;
-
- try_here =3D shadow_alloc;
- vg_assert(VG_IS_PAGE_ALIGNED(try_here));
- vg_assert(VG_IS_PAGE_ALIGNED(size));
- vg_assert(size > 0);
-
- if (0)
- VG_(printf)("shadow_alloc: size %d, trying at %p\n", size, (void*)=
try_here);
-
- /* this is big-bang allocated, so we don't expect to find a listed
- segment for it. */
- /* This is really an absolute disgrace. Sometimes the big-bang
- mapping is in the list (due to re-reads of /proc/self/maps,
- presumably) and sometimes it isn't. */
-#if 0
- r =3D find_segment(try_here);
- vg_assert(r =3D=3D -1);
- r =3D find_segment(try_here+size-1);
- vg_assert(r =3D=3D -1);
-#endif
-
- r =3D VG_(mprotect_native)( (void*)try_here,=20
- size, VKI_PROT_READ|VKI_PROT_WRITE );
-
- if (r.isError)
- goto failed;
-
- shadow_alloc +=3D size;
- return (void*)try_here;
-
- failed:
- VG_(printf)(
- "valgrind: Could not allocate address space (0x%x bytes)\n"
- "valgrind: for shadow memory chunk.\n",
- size
- );=20
- VG_(exit)(1);
-}
-
-/*------------------------------------------------------------*/
-/*--- pointercheck ---*/
-/*------------------------------------------------------------*/
-
-Bool VG_(setup_pointercheck)(Addr client_base, Addr client_end)
-{
-aspacem_barf("setup_pointercheck");
- vg_assert(0 !=3D client_end);
-#if defined(VGP_x86_linux)
- /* Client address space segment limit descriptor entry */
- #define POINTERCHECK_SEGIDX 1
-
- vki_modify_ldt_t ldt =3D {=20
- POINTERCHECK_SEGIDX, // entry_number
- client_base, // base_addr
- (client_end - client_base) / VKI_PAGE_SIZE, // limit
- 1, // seg_32bit
- 0, // contents: data, RW, non-expanding
- 0, // ! read_exec_only
- 1, // limit_in_pages
- 0, // ! seg not present
- 1, // useable
- };
- SysRes ret =3D VG_(do_syscall3)(__NR_modify_ldt, 1, (UWord)&ldt, size=
of(ldt));
- if (ret.isError) {
- VG_(message)(Vg_UserMsg,
- "Warning: ignoring --pointercheck=3Dyes, "
- "because modify_ldt failed (errno=3D%d)", ret.val);
- return False;
- } else {
- return True;
- }
-#elif defined(VGP_amd64_linux)
- if (0)=20
- VG_(message)(Vg_DebugMsg, "ignoring --pointercheck (unimplemented)=
");
- return True;
-#elif defined(VGP_ppc32_linux)
- if (0)=20
- VG_(message)(Vg_DebugMsg, "ignoring --pointercheck (unimplemented)=
");
- return True;
-#else
-# error Unknown architecture
-#endif
-}
-
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
@@ -1737,7 +562,7 @@
Int i;
VG_(debugLog)(logLevel, "aspacem",
"<<< SHOW_SEGMENTS: %s (%d segments, %d segnames)\n",=20
- who, segments_used, segnames_used);
+ who, nsegments_used, segnames_used);
for (i =3D 0; i < segnames_used; i++) {
if (!segnames[i].inUse)
continue;
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 22:32:51 UTC (rev 4685=
)
+++ branches/ASPACEM/coregrind/m_main.c 2005-09-19 23:25:26 UTC (rev 4686=
)
@@ -192,97 +192,6 @@
=20
=20
/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
-/*=3D=3D=3D Address space determination =
=3D=3D=3D*/
-/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
-
-// defined at the end of this file
-extern char _start[];
-
-static void layout_remaining_space(Addr argc_addr, float ratio)
-{
- SysRes res;
- Addr client_size, shadow_size;
-
- // VG_(valgrind_base) should have been set by scan_auxv, but if not,
- // this is a workable approximation
- if (VG_(valgrind_base) =3D=3D 0) {
- VG_(valgrind_base) =3D VG_PGROUNDDN(&_start);
- }
-
- VG_(valgrind_last) =3D VG_ROUNDUP(argc_addr, 0x10000) - 1; // stack
-
- // This gives the client the largest possible address space while
- // taking into account the tool's shadow needs.
- client_size =3D VG_ROUNDDN((VG_(valgrind_base)-REDZONE_SIZE) =
/ (1.+ratio),
- CLIENT_SIZE_MULTIPLE);
- VG_(client_base) =3D 0;
- VG_(client_end) =3D VG_(client_base) + client_size;
- /* where !FIXED mmap goes */
- VG_(client_mapbase) =3D VG_(client_base) +
- VG_PGROUNDDN((Addr)(client_size * CLIENT_HEAP_PROPORTION));
-
- VG_(shadow_base) =3D VG_(client_end) + REDZONE_SIZE;
- VG_(shadow_end) =3D VG_(valgrind_base);
- shadow_size =3D VG_(shadow_end) - VG_(shadow_base);
-
-#define SEGSIZE(a,b) ((VG_(b) - VG_(a))/(1024*1024))
-
- if (0)
- VG_(printf)(
- "client_base %p (%dMB)\n"
- "client_mapbase %p (%dMB)\n"
- "client_end %p (%dMB)\n"
- "shadow_base %p (%dMB)\n"
- "shadow_end %p\n"
- "valgrind_base %p (%dMB)\n"
- "valgrind_last %p\n",
- VG_(client_base), SEGSIZE(client_base, client_mapba=
se),
- VG_(client_mapbase), SEGSIZE(client_mapbase, client_end),
- VG_(client_end), SEGSIZE(client_end, shadow_base)=
,
- VG_(shadow_base), SEGSIZE(shadow_base, shadow_end),
- VG_(shadow_end),
- VG_(valgrind_base), SEGSIZE(valgrind_base, valgrind_las=
t),
- VG_(valgrind_last)
- );
-
-#undef SEGSIZE
-
- // Ban redzone
- res =3D VG_(mmap_native)((void *)VG_(client_end), REDZONE_SIZE, VKI_P=
ROT_NONE,
- VKI_MAP_FIXED|VKI_MAP_ANONYMOUS|VKI_MAP_PRIVATE|VKI_MAP_N=
ORESERVE,
- -1, 0);
- vg_assert(!res.isError);
-
- // Make client hole
- res =3D VG_(munmap_native)((void*)VG_(client_base), client_size);
- vg_assert(!res.isError);
-
- // Map shadow memory.
- // Initially all inaccessible, incrementally initialized as it is use=
d
- if (shadow_size !=3D 0) {
- res =3D VG_(mmap_native)((char *)VG_(shadow_base), shadow_size,
- VKI_PROT_NONE,
- VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_FIXED|VKI_MA=
P_NORESERVE,
- -1, 0);
- if (res.isError) {
- VG_(printf)(
- "valgrind: Could not allocate address space (%p bytes)\n"
- "valgrind: for shadow memory\n"
- "valgrind: Possible causes:\n"
- "valgrind: - For some systems (especially under RedHat 8), Val=
grind\n"
- "valgrind: needs at least 1.5GB swap space.\n"
- "valgrind: - Or, your virtual memory size may be limited (chec=
k\n"
- "valgrind: with 'ulimit -v').\n"
- "valgrind: - Or, your system may use a kernel that provides on=
ly a\n"=20
- "valgrind: too-small (eg. 2GB) user address space.\n"
- , (void*)shadow_size
- );=20
- VG_(exit)(1);
- }
- }
-}
-
-/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
/*=3D=3D=3D Environment and stack setup =
=3D=3D=3D*/
/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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
@@ -1777,116 +1686,7 @@
VG_(clexecfd) =3D VG_(safe_fd)( VG_(clexecfd) );
}
=20
-/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
-/*=3D=3D=3D Initialise program data/text, etc. =
=3D=3D=3D*/
-/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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
-static void build_valgrind_map_callback ( Addr start, SizeT size, UInt p=
rot,
- UInt dev, UInt ino, ULong foffset,=20
- const UChar* filename )
-{
- /* Only record valgrind mappings for now, without loading any
- symbols. This is so we know where the free space is before we
- start allocating more memory (note: heap is OK, it's just mmap
- which is the problem here). */
- if (start >=3D VG_(client_end) && start < VG_(valgrind_last)) {
- VG_(debugLog)(2, "main",
- "valgrind-seg: %p-%p prot 0x%x file=3D%s\n",
- (void*)start, (void*)(start+size), prot, filename);
- VG_(map_file_segment)(start, size, prot,
- SF_MMAP|SF_NOSYMS|SF_VALGRIND,
- dev, ino, foffset, filename);
- /* update VG_(valgrind_last) if it looks wrong */
- if (start+size > VG_(valgrind_last))
- VG_(valgrind_last) =3D start+size-1;
- }
-}
-
-// Global var used to pass local data to callback
-Addr sp_at_startup___global_arg =3D 0;
-
-/*=20
- This second pass adds in client mappings, and loads symbol tables
- for all interesting mappings. The trouble is that things can
- change as we go, because we're calling the Tool to track memory as
- we find it.
-
- So for Valgrind mappings, we don't replace any mappings which
- aren't still identical (which will include the .so mappings, so we
- will load their symtabs)>
- */
-static void build_segment_map_callback ( Addr start, SizeT size, UInt pr=
ot,
- UInt dev, UInt ino, ULong foffset,
- const UChar* filename )
-{
- UInt flags;
- Bool is_stack_segment;
- Addr r_esp;
-
- is_stack_segment=20
- =3D (start =3D=3D VG_(clstk_base) && (start+size) =3D=3D VG_(clstk=
_end));
-
- VG_(debugLog)(2, "main",
- "any-seg: %p-%p prot 0x%x stack=3D%d file=3D%s\n",
- (void*)start, (void*)(start+size), prot, is_stack_segme=
nt,=20
- filename);
-
- if (is_stack_segment)
- flags =3D SF_STACK | SF_GROWDOWN;
- else
- flags =3D SF_MMAP;
-
- if (filename !=3D NULL)
- flags |=3D SF_FILE;
-
-#if 0
- // This needs to be fixed properly. jrs 20050307
- if (start >=3D VG_(client_end) && start < VG_(valgrind_last)) {
- Segment *s =3D VG_(find_segment_before)(start);
-
- /* We have to be a bit careful about inserting new mappings into
- the Valgrind part of the address space. We're actively
- changing things as we parse these mappings, particularly in
- shadow memory, and so we don't want to overwrite those
- changes. Therefore, we only insert/update a mapping if it is
- mapped from a file or it exactly matches an existing mapping.
-
- NOTE: we're only talking about the Segment list mapping
- metadata; this doesn't actually mmap anything more. */
- if (filename || (s && s->addr =3D=3D start && s->len =3D=3D size))=
{
- flags |=3D SF_VALGRIND;
- VG_(map_file_segment)(start, size, prot, flags, dev, ino, foffset, fil=
ename);
- } else {
- /* assert range is already mapped */
- vg_assert(VG_(is_addressable)(start, size, VKI_PROT_NONE));
- }
- } else
-#endif
- VG_(map_file_segment)(start, size, prot, flags, dev, ino, foffset,=
filename);
-
- if (VG_(is_client_addr)(start) && VG_(is_client_addr)(start+size-1)) =
{
- VG_TRACK( new_mem_startup, start, size,
- !!(prot & VKI_PROT_READ),=20
- !!(prot & VKI_PROT_WRITE),=20
- !!(prot & VKI_PROT_EXEC));
- }
-
- /* If this is the stack segment mark all below %esp as noaccess. */
- r_esp =3D sp_at_startup___global_arg;
- vg_assert(0 !=3D r_esp);
- if (is_stack_segment) {
- if (0) {
- VG_(message)(Vg_DebugMsg, "invalidating stack area: %p .. %p",
- start,r_esp);
- VG_(message)(Vg_DebugMsg, " validating stack area: %p .. %p",
- r_esp, start+size);
- }
- VG_TRACK( die_mem_stack, start, r_esp-start );
- // what's this for?
- //VG_TRACK( post_mem_write, r_esp, (start+size)-r_esp );
- }
-}
-
/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
/*=3D=3D=3D Initialise the first thread. =
=3D=3D=3D*/
/*=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D*/
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 22:32:51 UTC (re=
v 4685)
+++ branches/ASPACEM/coregrind/m_stacktrace.c 2005-09-19 23:25:26 UTC (re=
v 4686)
@@ -184,7 +184,7 @@
useful. */
if (ip >=3D (Addr)&VG_(trampoline_stuff_start)=20
&& ip < (Addr)&VG_(trampoline_stuff_end)
- && VG_(is_addressable)(sp, sizeof(Addr), VKI_PROT_READ)) {
+ && VG_(am_is_valid_for_client)(sp, sizeof(Addr), VKI_PROT_READ)) =
{
ip =3D *(Addr *)sp;
sp +=3D sizeof(Addr);
}
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-19 22:=
32:51 UTC (rev 4685)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-generic.c 2005-09-19 23:=
25:26 UTC (rev 4686)
@@ -1627,7 +1627,8 @@
=20
if (!(arg2 & 010000)) /* =3D SHM_RDONLY */
prot &=3D ~VKI_PROT_WRITE;
- VG_(map_segment)(res, segmentSize, prot, SF_SHARED|SF_SHM);
+ VG_(am_notify_client_mmap)( res, segmentSize,=20
+ prot, VKI_MAP_ANONYMOUS, 0,0);
}
}
=20
@@ -1643,11 +1644,13 @@
void
ML_(generic_POST_sys_shmdt) ( ThreadId tid, UWord res, UWord arg0 )
{
- Segment *s =3D VG_(find_segment)(arg0);
+ NSegment *s =3D VG_(am_find_nsegment)(arg0);
=20
- if (s !=3D NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg0, =
1)) {
- VG_TRACK( die_mem_munmap, s->addr, s->len );
- VG_(unmap_range)(s->addr, s->len);
+ if (s !=3D NULL /* && (s->flags & SF_SHM) */
+ /* && Implied by defn of am_find_nsegment:
+ VG_(seg_contains)(s, arg0, 1) */) {
+ VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
+ VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
}
}
/* ------ */
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-19 22:32=
:51 UTC (rev 4685)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-linux.c 2005-09-19 23:25=
:26 UTC (rev 4686)
@@ -678,41 +678,47 @@
// the padding is in place.
PRE(sys_io_setup)
{
- SizeT size;
- Addr addr;
+ // JRS 19 Sept 2005: this wrapper might be a lot easier with the
+ // new aspacemgr in place. No need to do address space padding/
+ // unpadding; just let the kernel do what the hell it likes and
+ // notify aspacem of the results afterwards. For now, however:
+ SET_STATUS_Failure( VKI_ENOSYS );
=20
- PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
- PRE_REG_READ2(long, "io_setup",
- unsigned, nr_events, vki_aio_context_t *, ctxp);
- PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
- =20
- size =3D VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
- ARG1*sizeof(struct vki_io_event));
- addr =3D VG_(find_map_space)(0, size, True);
- =20
- if (addr =3D=3D 0) {
- SET_STATUS_Failure( VKI_ENOMEM );
- return;
- }
-
- VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, 0);
- =20
- VG_(pad_address_space)(0);
- SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
- VG_(unpad_address_space)(0);
-
- if (SUCCESS && RES =3D=3D 0) {
- struct vki_aio_ring *r =3D *(struct vki_aio_ring **)ARG2;
- =20
- vg_assert(addr =3D=3D (Addr)r);
- vg_assert(ML_(valid_client_addr)(addr, size, tid, "io_setup"));
- =20
- VG_TRACK( new_mem_mmap, addr, size, True, True, False );
- POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
- }
- else {
- VG_(unmap_range)(addr, size);
- }
+// SizeT size;
+// Addr addr;
+//
+// PRINT("sys_io_setup ( %u, %p )", ARG1,ARG2);
+// PRE_REG_READ2(long, "io_setup",
+// unsigned, nr_events, vki_aio_context_t *, ctxp);
+// PRE_MEM_WRITE( "io_setup(ctxp)", ARG2, sizeof(vki_aio_context_t) );
+// =20
+// size =3D VG_PGROUNDUP(sizeof(struct vki_aio_ring) +
+// ARG1*sizeof(struct vki_io_event));
+// addr =3D VG_(find_map_space)(0, size, True);
+// =20
+// if (addr =3D=3D 0) {
+// SET_STATUS_Failure( VKI_ENOMEM );
+// return;
+// }
+//
+// VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, 0);
+// =20
+// VG_(pad_address_space)(0);
+// SET_STATUS_from_SysRes( VG_(do_syscall2)(SYSNO, ARG1, ARG2) );
+// VG_(unpad_address_space)(0);
+//
+// if (SUCCESS && RES =3D=3D 0) {
+// struct vki_aio_ring *r =3D *(struct vki_aio_ring **)ARG2;
+// =20
+// vg_assert(addr =3D=3D (Addr)r);
+// vg_assert(ML_(valid_client_addr)(addr, size, tid, "io_setup"));
+// =20
+// VG_TRACK( new_mem_mmap, addr, size, True, True, False );
+// POST_MEM_WRITE( ARG2, sizeof(vki_aio_context_t) );
+// }
+// else {
+// VG_(unmap_range)(addr, size);
+// }
}
=20
// Nb: This wrapper is "Special" because we need 'size' to do the unmap
@@ -724,8 +730,9 @@
// XXX This segment can be implicitly unmapped when aio
// file-descriptors are closed...
PRE(sys_io_destroy)
-{ =20
- Segment *s =3D VG_(find_segment)(ARG1);
+{
+ SET_STATUS_Failure( VKI_ENOSYS );
+ NSegment *s =3D VG_(am_find_nsegment)(ARG1);
struct vki_aio_ring *r;
SizeT size;
=20
@@ -740,14 +747,18 @@
=20
SET_STATUS_from_SysRes( VG_(do_syscall1)(SYSNO, ARG1) );
=20
+ /* jrs 20050917: testing s here seems nonsensical. Even if s is
+ NULL, the syscall might have succeeded, and so if s is null then
+ neither the tool nor aspacem will be notified. */
if (SUCCESS && RES =3D=3D 0 && s !=3D NULL) {=20
VG_TRACK( die_mem_munmap, ARG1, size );
- VG_(unmap_range)(ARG1, size);
+ VG_(am_notify_munmap)(ARG1, size);
} =20
} =20
=20
PRE(sys_io_getevents)
{
+ SET_STATUS_Failure( VKI_ENOSYS );
*flags |=3D SfMayBlock;
PRINT("sys_io_getevents ( %llu, %lld, %lld, %p, %p )",
(ULong)ARG1,(Long)ARG2,(Long)ARG3,ARG4,ARG5);
Modified: branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-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-x86-linux.c 2005-09-19 2=
2:32:51 UTC (rev 4685)
+++ branches/ASPACEM/coregrind/m_syswrap/syswrap-x86-linux.c 2005-09-19 2=
3:25:26 UTC (rev 4686)
@@ -1028,21 +1028,24 @@
=20
if (ARG1 & VKI_CLONE_PARENT_SETTID) {
PRE_MEM_WRITE("clone(parent_tidptr)", ARG3, sizeof(Int));
- if (!VG_(is_addressable)(ARG3, sizeof(Int), VKI_PROT_WRITE)) {
+ if (!VG_(am_is_valid_for_client)(ARG3, sizeof(Int),=20
+ VKI_PROT_WRITE)) {
SET_STATUS_Failure( VKI_EFAULT );
return;
}
}
if (ARG1 & (VKI_CLONE_CHILD_SETTID | VKI_CLONE_CHILD_CLEARTID)) {
PRE_MEM_WRITE("clone(child_tidptr)", ARG5, sizeof(Int));
- if (!VG_(is_addressable)(ARG5, sizeof(Int), VKI_PROT_WRITE)) {
+ if (!VG_(am_is_valid_for_client)(ARG5, sizeof(Int),=20
+ VKI_PROT_WRITE)) {
SET_STATUS_Failure( VKI_EFAULT );
return;
}
}
if (ARG1 & VKI_CLONE_SETTLS) {
PRE_MEM_READ("clone(tls_user_desc)", ARG4, sizeof(vki_modify_ldt_t=
));
- if (!VG_(is_addressable)(ARG4, sizeof(vki_modify_ldt_t), VKI_PROT_=
READ)) {
+ if (!VG_(am_is_valid_for_client)(ARG4, sizeof(vki_modify_ldt_t),=20
+ VKI_PROT_READ)) {
SET_STATUS_Failure( VKI_EFAULT );
return;
}
Modified: branches/ASPACEM/coregrind/pub_core_mallocfree.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_mallocfree.h 2005-09-19 22:32:51 =
UTC (rev 4685)
+++ branches/ASPACEM/coregrind/pub_core_mallocfree.h 2005-09-19 23:25:26 =
UTC (rev 4686)
@@ -83,10 +83,6 @@
=20
extern void VG_(print_all_arena_stats) ( void );
=20
-// TODO: move somewhere else
-// Call here to bomb the system when out of memory (mmap anon fails)
-extern void VG_(out_of_memory_NORETURN) ( HChar* who, SizeT szB );
-
#endif // __PUB_CORE_MALLOCFREE_H
=20
/*--------------------------------------------------------------------*/
Modified: branches/ASPACEM/helgrind/hg_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/helgrind/hg_main.c 2005-09-19 22:32:51 UTC (rev 4685=
)
+++ branches/ASPACEM/helgrind/hg_main.c 2005-09-19 23:25:26 UTC (rev 4686=
)
@@ -501,7 +501,10 @@
//PROF_EVENT(10); PPP
=20
// Mark all words as virgin.
- map =3D (ESecMap *)VG_(shadow_alloc)(sizeof(ESecMap));
+ map =3D (ESecMap *)VG_(am_shadow_alloc)(sizeof(ESecMap));
+ if (map =3D=3D NULL)
+ VG_(out_of_memory_NORETURN)( "helgrind:allocate new ESecMap",=20
+ sizeof(ESecMap) );
for (i =3D 0; i < ESEC_MAP_WORDS; i++)
map->swords[i] =3D virgin_sword;
=20
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 22:32:51 UTC=
(rev 4685)
+++ branches/ASPACEM/include/pub_tool_aspacemgr.h 2005-09-19 23:25:26 UTC=
(rev 4686)
@@ -130,23 +130,10 @@
extern Bool VG_(am_is_valid_for_client) ( Addr start, SizeT len,=20
UInt prot );
=20
-extern Bool VG_(is_client_addr) (Addr a);
-
-extern Bool VG_(is_shadow_addr) (Addr a);
-
+// See pub_core_aspacemgr.h for description.
/* 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);
-
-/* Calls into the core used by leak-checking */
-
-/* Calls "add_rootrange" with each range of memory which looks like a
- plausible source of root pointers. This is very Memcheck-specific --
- it's used in leak detection.
-*/
-extern void VG_(find_root_memory)(void (*add_rootrange)(Addr addr, SizeT=
sz));
-
#endif // __PUB_TOOL_ASPACEMGR_H
=20
/*--------------------------------------------------------------------*/
Modified: branches/ASPACEM/include/pub_tool_libcmman.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_libcmman.h 2005-09-19 22:32:51 UTC =
(rev 4685)
+++ branches/ASPACEM/include/pub_tool_libcmman.h 2005-09-19 23:25:26 UTC =
(rev 4686)
@@ -31,9 +31,6 @@
#ifndef __PUB_TOOL_LIBCMMAN_H
#define __PUB_TOOL_LIBCMMAN_H
=20
-/* Get memory by anonymous mmap. */
-extern void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who );
-
#endif // __PUB_TOOL_LIBCMMAN_H
=20
/*--------------------------------------------------------------------*/
Modified: b...
[truncated message content] |