PERFORCE change 152140 for review
Peter Wemm
peter at FreeBSD.org
Wed Oct 29 08:15:00 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=152140
Change 152140 by peter at peter_overcee on 2008/10/29 08:14:03
Deal with the procfs map handler inserting stray newlines at random.
Write an alternative map reader that uses the KERN_PROC_VMMAP sysctl -
MUCH MUCH nicer to deal with, and hopefully it has my patch for kve_offset.
Affected files ...
.. //depot/projects/valgrind/coregrind/m_aspacemgr/aspacemgr-freebsd.c#8 edit
Differences ...
==== //depot/projects/valgrind/coregrind/m_aspacemgr/aspacemgr-freebsd.c#8 (text+ko) ====
@@ -1932,6 +1932,7 @@
if (!(flags & VKI_MAP_ANONYMOUS)) {
// Nb: We ignore offset requests in anonymous mmaps (see bug #126722)
seg.offset = offset;
+//VG_(printf)("XX:1 offset %#llx\n", offset);
if (get_inode_for_fd(fd, &dev, &ino, &mode)) {
seg.dev = dev;
seg.ino = ino;
@@ -2119,6 +2120,7 @@
if (!ok || advised != start)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
+//VG_(printf)("XX:2 offset %#lx\n", offset);
/* 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. */
@@ -2144,6 +2146,7 @@
seg.start = start;
seg.end = seg.start + VG_PGROUNDUP(length) - 1;
seg.offset = offset;
+//VG_(printf)("XX:3 offset %#llx\n", offset);
seg.hasR = toBool(prot & VKI_PROT_READ);
seg.hasW = toBool(prot & VKI_PROT_WRITE);
seg.hasX = toBool(prot & VKI_PROT_EXEC);
@@ -2394,6 +2397,7 @@
if (!ok)
return VG_(mk_SysRes_Error)( VKI_EINVAL );
+//VG_(printf)("XX:4 offset %#llx\n", offset);
/* 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. */
@@ -2419,6 +2423,7 @@
seg.start = sres.res;
seg.end = seg.start + VG_PGROUNDUP(length) - 1;
seg.offset = offset;
+//VG_(printf)("XX:5 offset %#llx\n", offset);
seg.hasR = toBool(prot & VKI_PROT_READ);
seg.hasW = toBool(prot & VKI_PROT_WRITE);
seg.hasX = toBool(prot & VKI_PROT_EXEC);
@@ -2882,6 +2887,7 @@
aspacem_assert(seg.kind == SkAnonC);
aspacem_assert(seg.offset == 0);
}
+//VG_(printf)("XX:6 offset %#llx\n", seg.offset);
seg.start = new_addr;
seg.end = new_addr + new_len - 1;
add_segment( &seg );
@@ -2905,6 +2911,81 @@
return True;
}
+#if __FreeBSD__ >= 7
+
+/* Size of a smallish table used to read /proc/self/map entries. */
+#define M_PROCMAP_BUF 100000
+
+/* static ... to keep it out of the stack frame. */
+static Char procmap_buf[M_PROCMAP_BUF];
+
+static void parse_procselfmaps (
+ void (*record_mapping)( Addr addr, SizeT len, UInt prot,
+ ULong dev, ULong ino, ULong offset,
+ const UChar* filename ),
+ void (*record_gap)( Addr addr, SizeT len )
+ )
+{
+ Int i;
+ Addr start, endPlusOne, gapStart;
+ UChar* filename;
+ UInt prot;
+ ULong foffset, dev, ino;
+ struct vki_kinfo_vmentry *kve;
+ vki_size_t len;
+ Int oid[4];
+ SysRes sres;
+
+//VG_(debugLog)(0, "procselfmaps", "DOING SYSCTL\n");
+ foffset = ino = 0; /* keep gcc-4.1.0 happy */
+
+ oid[0] = VKI_CTL_KERN;
+ oid[1] = VKI_KERN_PROC;
+ oid[2] = VKI_KERN_PROC_VMMAP;
+ oid[3] = VG_(do_syscall0)(__NR_getpid).res;
+ len = sizeof(procmap_buf);
+
+ sres = VG_(do_syscall6)(__NR___sysctl, (UWord)oid, 4, (UWord)procmap_buf, (UWord)&len, 0, 0);
+ if (sres.isError) {
+ VG_(debugLog)(0, "procselfmaps", "sysctl %ld\n", sres.err);
+ ML_(am_exit)(1);
+ }
+
+ gapStart = Addr_MIN;
+ i = 0;
+ kve = (struct vki_kinfo_vmentry *)procmap_buf;
+ for (i = 0; i < (len / sizeof(*kve)); i++, kve++) {
+ dev = ino = 0;
+
+ start = (UWord)kve->kve_start;
+ endPlusOne = (UWord)kve->kve_end;
+ foffset = kve->kve_offset;
+ filename = kve->kve_path;
+ if (filename[0] != '/') {
+ filename = NULL;
+ foffset = 0;
+ }
+
+ prot = 0;
+ if (kve->kve_protection & VKI_KVME_PROT_READ) prot |= VKI_PROT_READ;
+ if (kve->kve_protection & VKI_KVME_PROT_WRITE) prot |= VKI_PROT_WRITE;
+ if (kve->kve_protection & VKI_KVME_PROT_EXEC) prot |= VKI_PROT_EXEC;
+
+ if (record_gap && gapStart < start)
+ (*record_gap) ( gapStart, start-gapStart );
+
+ if (record_mapping && start < endPlusOne)
+ (*record_mapping) ( start, endPlusOne-start,
+ prot, dev, ino,
+ foffset, filename );
+ gapStart = endPlusOne;
+ }
+
+ if (record_gap && gapStart < Addr_MAX)
+ (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
+}
+
+#else
/*-----------------------------------------------------------------*/
/*--- ---*/
@@ -3073,6 +3154,10 @@
gapStart = Addr_MIN;
while (True) {
if (i >= buf_n_tot) break;
+ if (procmap_buf[i] == '\n') {
+ i++;
+ continue;
+ }
/* Read (without fscanf :) the pattern %8x %8x %d %d %8x %c%c%c%c %d %d %8x .* .* .* */
/* 0x38000000 0x38119000 281 748 0xd76df8a0 r-x 2 1 0x0 COW NC vnode */
@@ -3246,6 +3331,7 @@
if (record_gap && gapStart < Addr_MAX)
(*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
}
+#endif
/*--------------------------------------------------------------------*/
/*--- end ---*/
More information about the p4-projects
mailing list