case SkAnonV: return "ANON";
case SkFileC: return "file";
case SkFileV: return "FILE";
+ case SkShmC: return "shm ";
case SkResvn: return "RSVN";
default: return "????";
}
);
break;
- case SkAnonC: case SkAnonV:
+ case SkAnonC: case SkAnonV: case SkShmC:
VG_(debugLog)(
logLevel, "aspacem",
"%3d: %s %010llx-%010llx %s %c%c%c%c%c\n",
&& !s->hasR && !s->hasW && !s->hasX && !s->hasT
&& !s->isCH;
- case SkAnonC: case SkAnonV:
+ case SkAnonC: case SkAnonV: case SkShmC:
return
s->smode == SmFixed
&& s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1
}
break;
+ case SkShmC:
+ return False;
+
default:
break;
same = nsegments[i].kind == SkAnonC
|| nsegments[i].kind == SkAnonV
|| nsegments[i].kind == SkFileC
- || nsegments[i].kind == SkFileV;
+ || nsegments[i].kind == SkFileV
+ || nsegments[i].kind == SkShmC;
seg_prot = 0;
if (nsegments[i].hasR) seg_prot |= VKI_PROT_READ;
return NULL;
}
switch (nsegments[i].kind) {
- case SkFileC: case SkFileV:
+ case SkFileC: case SkFileV: case SkShmC:
case SkAnonC: case SkAnonV: case SkResvn:
return &nsegments[i];
default:
for (i = iLo; i <= iHi; i++) {
if ( (nsegments[i].kind == SkFileC
|| nsegments[i].kind == SkAnonC
+ || nsegments[i].kind == SkShmC
|| (nsegments[i].kind == SkFree && freeOk)
|| (nsegments[i].kind == SkResvn && freeOk))
&& (needR ? nsegments[i].hasR : True)
if (nsegments[i].kind == SkFree
|| nsegments[i].kind == SkFileC
|| nsegments[i].kind == SkAnonC
+ || nsegments[i].kind == SkShmC
|| nsegments[i].kind == SkResvn) {
/* ok */
} else {
return needDiscard;
}
+/* Notifies aspacem that the client completed a shmat successfully.
+ The segment array is updated accordingly. If the returned Bool is
+ True, the caller should immediately discard translations from the
+ specified address range. */
+
+Bool
+VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot )
+{
+ NSegment seg;
+ Bool needDiscard;
+
+ aspacem_assert(len > 0);
+ aspacem_assert(VG_IS_PAGE_ALIGNED(a));
+ aspacem_assert(VG_IS_PAGE_ALIGNED(len));
+
+ /* Discard is needed if any of the just-trashed range had T. */
+ needDiscard = any_Ts_in_range( a, len );
+
+ init_nsegment( &seg );
+ seg.kind = SkShmC;
+ seg.start = a;
+ seg.end = a + len - 1;
+ seg.offset = 0;
+ seg.hasR = toBool(prot & VKI_PROT_READ);
+ seg.hasW = toBool(prot & VKI_PROT_WRITE);
+ seg.hasX = toBool(prot & VKI_PROT_EXEC);
+ add_segment( &seg );
+ AM_SANITY_CHECK;
+ return needDiscard;
+}
+
/* Notifies aspacem that an mprotect was completed successfully. The
segment array is updated accordingly. Note, as with
VG_(am_notify_munmap), it is not the job of this function to reject
for (i = iLo; i <= iHi; i++) {
/* Apply the permissions to all relevant segments. */
switch (nsegments[i].kind) {
- case SkAnonC: case SkAnonV: case SkFileC: case SkFileV:
+ case SkAnonC: case SkAnonV: case SkFileC: case SkFileV: case SkShmC:
nsegments[i].hasR = newR;
nsegments[i].hasW = newW;
nsegments[i].hasX = newX;
cope with the discrepancy, aspacem's sync checker omits the
dev/ino correspondence check in cases where V does not know
the dev/ino. */
- d = VG_(am_notify_client_mmap)( res, VG_PGROUNDUP(segmentSize),
- prot, VKI_MAP_ANONYMOUS, 0,0);
+ d = VG_(am_notify_client_shmat)( res, VG_PGROUNDUP(segmentSize), prot );
/* we don't distinguish whether it's read-only or
* read-write -- it doesn't matter really. */
if (s != NULL) {
Addr s_start = s->start;
SizeT s_len = s->end+1 - s->start;
- Bool d = VG_(am_notify_munmap)(s_start, s_len);
+ Bool d;
+
+ vg_assert(s->kind == SkShmC && s->start == arg0);
+
+ d = VG_(am_notify_munmap)(s_start, s_len);
s = NULL; /* s is now invalid */
VG_TRACK( die_mem_munmap, s_start, s_len );
if (d)
extern Bool VG_(am_notify_client_mmap)
( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
+/* Notifies aspacem that the client completed a shmat successfully.
+ The segment array is updated accordingly. If the returned Bool is
+ True, the caller should immediately discard translations from the
+ specified address range. */
+extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
+
/* Notifies aspacem that an mprotect was completed successfully. The
segment array is updated accordingly. Note, as with
VG_(am_notify_munmap), it is not the job of this function to reject
SkAnonV, // anonymous mapping belonging to valgrind
SkFileC, // file mapping belonging to the client
SkFileV, // file mapping belonging to valgrind
+ SkShmC, // shared memory segment belonging to the client
SkResvn // reservation
}
SegKind;
// there is an associated file
// segment may have permissions
+ kind == SkShmC:
+ // smode==SmFixed
+ // there's no associated file:
+ dev==ino==foff = 0, fnidx == -1
+ // segment may have permissions
+
kind == SkResvn
// the segment may be resized if required
// there's no associated file: