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>