Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Oct 2008 08:15:00 GMT
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 152140 for review
Message-ID:  <200810290815.m9T8F0XL071639@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=152140

Change 152140 by peter@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                                                          ---*/



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810290815.m9T8F0XL071639>