--- coregrind/m_transtab.c.orig	Wed Nov 26 04:41:21 2014
+++ coregrind/m_transtab.c	Mon Dec 10 17:05:02 2018
@@ -749,6 +749,10 @@
    /* Get the CPU info established at startup. */
    VexArch     arch_host = VexArch_INVALID;
    VexArchInfo archinfo_host;
+#if defined(__OpenBSD__)
+   UInt        len;
+   SysRes      sres;
+#endif
    VG_(bzero_inline)(&archinfo_host, sizeof(archinfo_host));
    VG_(machine_get_VexArchInfo)( &arch_host, &archinfo_host );
    VexEndness endness_host = archinfo_host.endness;
@@ -789,6 +793,18 @@

    TTEntry* from_tte = index_tte(from_sNo, from_tteNo);

+#if defined(__OpenBSD__)
+   /* Protect the host code areas. */
+   len = (Long)sectors[to_sNo].tc_next - (Long)host_code;
+   sres = VG_(am_do_mprotect_NO_NOTIFY)(
+      (Addr)sectors[to_sNo].tc, 8 * tc_sector_szQ, VKI_PROT_READ | VKI_PROT_WRITE
+   );
+   if (sr_isError(sres)) {
+      VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
+      vg_assert(0);
+   }
+#endif
+
    /* Get VEX to do the patching itself.  We have to hand it off
       since it is host-dependent. */
    VexInvalRange vir
@@ -802,6 +818,17 @@
         );
    VG_(invalidate_icache)( (void*)vir.start, vir.len );

+#if defined(__OpenBSD__)
+   /* Protect the host code areas. */
+   sres = VG_(am_do_mprotect_NO_NOTIFY)(
+      (Addr)sectors[to_sNo].tc, 8 * tc_sector_szQ, VKI_PROT_READ | VKI_PROT_EXEC
+   );
+   if (sr_isError(sres)) {
+      VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
+      vg_assert(0);
+   }
+#endif
+
    /* Now do the tricky bit -- update the ch_succs and ch_preds info
       for the two translations involved, so we can undo the chaining
       later, which we will have to do if the to_ block gets removed
@@ -1530,6 +1550,9 @@
    ULong  *tcptr, *tcptr2;
    UChar* srcP;
    UChar* dstP;
+#if defined(__OpenBSD__)
+   SysRes sres;
+#endif

    vg_assert(init_done);
    vg_assert(vge->n_used >= 1 && vge->n_used <= 3);
@@ -1629,12 +1629,34 @@
    tcptr = sectors[y].tc_next;
    vg_assert(tcptr >= &sectors[y].tc[0]);
    vg_assert(tcptr <= &sectors[y].tc[tc_sector_szQ]);
+ 
+#if defined(__OpenBSD__)
+   /* Protect the host code areas. */
+   sres = VG_(am_do_mprotect_NO_NOTIFY)(
+      (Addr)sectors[y].tc, 8 * tc_sector_szQ, VKI_PROT_READ | VKI_PROT_WRITE
+   );
+   if (sr_isError(sres)) {
+      VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
+      vg_assert(0);
+   }
+#endif
 
    dstP = (UChar*)tcptr;
    srcP = (UChar*)code;
    VG_(memcpy)(dstP, srcP, code_len);
    sectors[y].tc_next += reqdQ;
    sectors[y].tt_n_inuse++;
+ 
+#if defined(__OpenBSD__)
+   /* Protect the host code areas. */
+   sres = VG_(am_do_mprotect_NO_NOTIFY)(
+      (Addr)sectors[y].tc, 8 * tc_sector_szQ, VKI_PROT_READ | VKI_PROT_EXEC
+   );
+   if (sr_isError(sres)) {
+      VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
+      vg_assert(0);
+   }
+#endif
 
    /* more paranoia */
    tcptr2 = sectors[y].tc_next;
