--- coregrind/m_aspacemgr/aspacemgr-linux.c.orig
+++ coregrind/m_aspacemgr/aspacemgr-linux.c
@@ -30,7 +30,7 @@
    The GNU General Public License is contained in the file COPYING.
 */
 
-#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd)
+#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris) || defined(VGO_freebsd) || defined(VGO_openbsd)
 
 /* *************************************************************
    DO NOT INCLUDE ANY OTHER FILES HERE.
@@ -314,7 +314,7 @@
 # endif
 #elif defined(VGO_solaris)
    = (Addr) 0x00100000; // 1MB
-#elif defined(VGO_freebsd)
+#elif defined(VGO_freebsd) || defined(VGO_openbsd)
    = (Addr) 0x04000000; // 64M
 #else
 #endif
@@ -685,6 +685,7 @@
          break;
 
       case SkFileC: case SkFileV:
+#if !defined(VGO_openbsd)
          if (s1->hasR == s2->hasR 
              && s1->hasW == s2->hasW && s1->hasX == s2->hasX
              && s1->dev == s2->dev && s1->ino == s2->ino
@@ -695,6 +696,25 @@
             ML_(am_dec_refcount)(s1->fnIdx);
             return True;
          }
+         // The following is an excerpt from `readelf -l a.out'.
+         //
+         // LOAD    0x0000000000000e20 0x0000000000002e20 0x0000000000002e20
+         //         0x00000000000001e0 0x00000000000001e0  RW     1000
+         // LOAD    0x0000000000001000 0x0000000000003000 0x0000000000003000
+         //         0x0000000000000000 0x0000000000000055  RW     1000
+         //
+         // The above two areas are determined to be contiguous area in the
+         // above `if' statement, and they are merged by preen_nsegments().
+         // Then, di->fsm.rw_map_count in the following `if' statement in
+         // VG_(di_notify_mmap)() would be 1, which does not match
+         // rw_load_count, and di_notify_ACHIEVE_ACCEPT_STATE() is not called.
+         // In the above program header, rw_load_count is 2.
+         //
+         //   if (di->fsm.have_rx_map &&
+         //       rw_load_count >= 1 &&
+         //       di->fsm.rw_map_count == rw_load_count) {
+         //      return di_notify_ACHIEVE_ACCEPT_STATE ( di );
+#endif
          break;
 
       case SkShmC:
@@ -1550,7 +1570,7 @@
    if (filename || (dev != 0 && ino != 0)) 
       seg.kind = SkFileV;
 
-#  if defined(VGO_darwin)
+#  if defined(VGO_darwin) || defined(VGO_openbsd)
    // GrP fixme no dev/ino on darwin
    if (offset != 0) 
       seg.kind = SkFileV;
@@ -2697,7 +2717,11 @@
       a client request to call the outer VG_(am_get_advisory). */
    sres = VG_(am_do_mmap_NO_NOTIFY)( 
              advised, length, 
+#if defined(VGO_openbsd)
+             VKI_PROT_READ|VKI_PROT_WRITE,
+#else
              VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, 
+#endif
              VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 
              VM_TAG_VALGRIND, 0
           );
@@ -2742,6 +2766,54 @@
    return sres;
 }
 
+#if defined(VGO_openbsd)
+SysRes VG_(am_mmap_anon_float_valgrind_stack)( SizeT length )
+{
+   SysRes     sres;
+   NSegment   seg;
+   Addr       advised;
+   Bool       ok;
+   MapRequest req;
+
+   /* Not allowable. */
+   if (length == 0)
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
+
+   /* Ask for an advisory.  If it's negative, fail immediately. */
+   req.rkind = MAny;
+   req.start = 0;
+   req.len   = length;
+   advised = VG_(am_get_advisory)( &req, False/*forClient*/, &ok );
+   if (!ok)
+      return VG_(mk_SysRes_Error)( VKI_EINVAL );
+
+   /* 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. */
+   sres = VG_(am_do_mmap_NO_NOTIFY)(
+             advised, length,
+             VKI_PROT_READ|VKI_PROT_WRITE,
+             VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_STACK,
+             VM_TAG_VALGRIND, 0
+          );
+   if (sr_isError(sres))
+      return sres;
+
+   /* Ok, the mapping succeeded.  Now notify the interval map. */
+   init_nsegment( &seg );
+   seg.kind  = SkAnonV;
+   seg.start = sr_Res(sres);
+   seg.end   = seg.start + VG_PGROUNDUP(length) - 1;
+   seg.hasR  = True;
+   seg.hasW  = True;
+   seg.hasX  = True;
+   add_segment( &seg );
+
+   AM_SANITY_CHECK;
+   return sres;
+}
+#endif
+
 /* Really just a wrapper around VG_(am_mmap_anon_float_valgrind). */
 
 SysRes VG_(am_shadow_alloc)(SizeT size)
@@ -3896,10 +3968,14 @@
 /*------END-procmaps-parser-for-Darwin---------------------------*/
 
 /*------BEGIN-procmaps-parser-for-Freebsd------------------------*/
-#elif defined(VGO_freebsd)
+#elif defined(VGO_freebsd) || defined(VGO_openbsd)
 
+#if defined(VGO_freebsd)
 /* Size of a smallish table used to read /proc/self/map entries. */
-#define M_PROCMAP_BUF 10485760	/* 10M */
+ #define M_PROCMAP_BUF 10485760	/* 10M */
+#else
+ #define M_PROCMAP_BUF (sizeof(struct vki_kinfo_vmentry) * 64/* XXX */)
+#endif
 
 /* static ... to keep it out of the stack frame. */
 static char procmap_buf[M_PROCMAP_BUF];
@@ -3911,6 +3987,7 @@
       void (*record_gap)( Addr addr, SizeT len )
    )
 {
+#if defined(VGO_freebsd)
     Addr   start, endPlusOne, gapStart;
     char* filename;
     char   *p;
@@ -3968,6 +4045,57 @@
  
     if (record_gap && gapStart < Addr_MAX)
        (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
+#elif defined(VGO_openbsd)
+#define	rounddown(x, y)	(((x)/(y))*(y))
+    Int mib[3];
+    Int res;
+    struct vki_kinfo_vmentry *kve;
+    vki_size_t len;
+    char *p;
+    Addr gapStart;
+
+    mib[0] = VKI_CTL_KERN;
+    mib[1] = VKI_KERN_PROC_VMMAP;
+    mib[2] = sr_Res(VG_(do_syscall0)(__NR_getpid));
+    len = rounddown(M_PROCMAP_BUF, sizeof(struct vki_kinfo_vmentry));
+    res = VG_(sysctl)(mib, 3, procmap_buf, &len, NULL, 0);
+    if (res) {
+       VG_(debugLog)(0, "procselfmaps", "sysctll %ld\n", res);
+       ML_(am_exit)(1);
+    }
+
+    gapStart = Addr_MIN;
+    p = procmap_buf;
+    while (p < (char *)procmap_buf + len) {
+       Addr start, endPlusOne;
+       ULong foffset, dev, ino;
+       UInt prot;
+
+       kve = (struct vki_kinfo_vmentry *)p;
+       start = (UWord)kve->kve_start;
+       endPlusOne = (UWord)kve->kve_end;
+       foffset = kve->kve_offset;
+       dev = 0; // XXX kve->kve_dev;
+       ino = 0; // XXX kve->kve_ino;
+
+       prot = 0;
+       if (kve->kve_protection & VKI_KVE_PROT_READ)  prot |= VKI_PROT_READ;
+       if (kve->kve_protection & VKI_KVE_PROT_WRITE) prot |= VKI_PROT_WRITE;
+       if (kve->kve_protection & VKI_KVE_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, NULL );
+       gapStart = endPlusOne;
+       p += sizeof(*kve);
+    }
+
+    if (record_gap && gapStart < Addr_MAX)
+       (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
+#endif
 }
 
 /*------END-procmaps-parser-for-Freebsd--------------------------*/
