On Tue Oct 01, 2019 at 03:54:32PM +0900, Masato Asou wrote:
> From: Masato Asou <[email protected]>
> Date: Fri, 27 Sep 2019 13:18:50 +0900 (JST)
>
> > Hi ports,
> >
> > This is a patch for running valgrind memcheck on amd64. I corrected
> > the following two problems.
> >
> > - FS register can be used.
> > - Fixed a problem that strip command rewrites offset and align of
> > memcheck ELF file.
>
> Additional information:
>
> - Abort trap was occurred when lounched valgrind.
>
> $ cd /usr/ports/devel/valgrind
> $ make && doas make install
> $ valgrind /bin/ls
> Abort trap
> $
>
> Sorry, I lost --strip-all option into
> coregrind/link_tool_exe_openbsd.in.
>
> New patch is below:
Thanks Masato Asou
I can confirm this patch fixes valgrind on amd64. I'm not in the
position to evaluate the quality of the patch, however it unbreaks
valgrind for me.
RS
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/valgrind/Makefile,v
> retrieving revision 1.19
> diff -u -p -r1.19 Makefile
> --- Makefile 12 Jul 2019 20:46:03 -0000 1.19
> +++ Makefile 27 Sep 2019 03:08:46 -0000
> @@ -38,4 +38,10 @@ AUTORECONF = /bin/sh ./autogen.sh
> .if ${PROPERTIES:Mclang}
> # replace -lgcc
> MAKE_FLAGS = TOOL_LDADD_COMMON=-lcompiler_rt
> +# XXX The '-s' option was not specified when executing the install command.
> +# Instead '--strip-all' is now executed at link time.
> +# strip command rewrite offset and align in ELF file. Therefor, when valgrind
> +# launch memcheck-amd64-openbsd, an Abort trap occurs in the execvp() system
> +# call.
> +INSTALL_STRIP =
> .endif
> Index: patches/patch-VEX_priv_guest_amd64_helpers_c
> ===================================================================
> RCS file: patches/patch-VEX_priv_guest_amd64_helpers_c
> diff -N patches/patch-VEX_priv_guest_amd64_helpers_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_guest_amd64_helpers_c 27 Sep 2019 03:08:46
> -0000
> @@ -0,0 +1,16 @@
> +--- VEX/priv/guest_amd64_helpers.c.orig
> ++++ VEX/priv/guest_amd64_helpers.c
> +@@ -3744,6 +3744,13 @@ void LibVEX_GuestAMD64_initialise (
> /*OUT*/VexGuestAMD64State* vex_state )
> + /* HACK: represent the offset associated with %fs==0. This
> + assumes that %fs is only ever zero. */
> + vex_state->guest_FS_ZERO = 0;
> ++#if defined(__OpenBSD__)
> ++{
> ++ int fs;
> ++ __asm__("mov %%fs,%0" : "=r" (fs));
> ++ vex_state->guest_FS_ZERO = fs;
> ++}
> ++#endif
> +
> + vex_state->guest_RIP = 0;
> +
> Index: patches/patch-VEX_priv_guest_amd64_toIR_c
> ===================================================================
> RCS file: patches/patch-VEX_priv_guest_amd64_toIR_c
> diff -N patches/patch-VEX_priv_guest_amd64_toIR_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_guest_amd64_toIR_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,205 @@
> +--- VEX/priv/guest_amd64_toIR.c.orig
> ++++ VEX/priv/guest_amd64_toIR.c
> +@@ -312,7 +312,11 @@ static IROp mkSizedOp ( IRType ty, IROp op8 )
> + || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
> + || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8
> + || op8 == Iop_CasCmpNE8
> ++#if !defined(__OpenBSD__)
> + || op8 == Iop_Not8 );
> ++#else
> ++ || op8 == Iop_Not8 || op8 == Iop_MovFromSeg8);
> ++#endif
> + switch (ty) {
> + case Ity_I8: return 0 +op8;
> + case Ity_I16: return 1 +op8;
> +@@ -709,6 +713,12 @@ static Bool haveF3 ( Prefix pfx ) {
> + return toBool((pfx & PFX_F3) > 0);
> + }
> +
> ++#if defined(__OpenBSD__)
> ++static Bool haveFS( Prefix pfx ) {
> ++ return toBool((pfx & PFX_FS) > 0);
> ++}
> ++#endif
> ++
> + static Bool have66 ( Prefix pfx ) {
> + return toBool((pfx & PFX_66) > 0);
> + }
> +@@ -1213,7 +1223,6 @@ static void putIRegRexB ( Int sz, Prefix pfx, UInt
> lo3bits, IRExpr* e )
> + ));
> + }
> +
> +-
> + /* Functions for getting register numbers from modrm bytes and REX
> + when we don't have to consider the complexities of integer subreg
> + accesses.
> +@@ -3137,6 +3146,136 @@ ULong dis_op2_G_E ( VexAbiInfo* vbi,
> + }
> +
> +
> ++#if defined(__OpenBSD__)
> ++/* Handle binary integer instructions of the form
> ++ op S, G, E meaning
> ++ op segment reg, reg, reg
> ++ Is passed the a ptr to the modRM byte, the actual operation, and the
> ++ data size. Returns the address advanced completely over this
> ++ instruction.
> ++
> ++ S(segment) is reg.
> ++ G(src) is reg.
> ++
> ++ OP %S:%G, tmp
> ++ PUT tmp, %E
> ++*/
> ++static
> ++Int dis_op3_S_G_E ( VexAbiInfo* vbi,
> ++ Prefix pfx,
> ++ IROp op,
> ++ Int size,
> ++ Long delta0,
> ++ /*OUT*/HChar* buf)
> ++{
> ++ IRType ty = szToITy(size);
> ++ IRTemp dst1 = newTemp(ty);
> ++ IRTemp off = newTemp(ty);
> ++ IRTemp dst0 = newTemp(ty);
> ++ Long delta = delta0;
> ++ UChar modrm = getUChar(delta0++);
> ++ UChar rm = (modrm & 7);
> ++
> ++ assign(dst0, getIRegG(size, pfx, modrm));
> ++ assign(off, getIRegE(size, pfx, modrm | 0xc0));
> ++ assign(dst1, binop(op, mkexpr(dst0), mkexpr(off)));
> ++ putIRegG(size, pfx, modrm, mkexpr(dst1));
> ++
> ++ if (rm == 0x4) {
> ++ UChar tmp = getUChar(delta0++);
> ++ vassert(tmp == 0x24);
> ++ } else if (rm == 0x05) {
> ++ UChar tmp = getUChar(delta0++);
> ++ vassert(tmp == 0x00);
> ++ }
> ++
> ++ DIS(buf, "%s(%s)", segRegTxt(pfx),
> ++ nameIRegRexB(haveASO(pfx) ? 4 : 8, pfx, rm));
> ++
> ++ return delta0 - delta;
> ++}
> ++
> ++static void
> ++dis_op3_assignDst(IROp op, Int size, IRTemp src, IRTemp dst, IRTemp off)
> ++{
> ++ switch (size) {
> ++ case 4: {
> ++ IRTemp src1 = newTemp(szToITy(8));
> ++ assign(src1, unop(Iop_32Uto64, mkexpr(src)));
> ++ assign(dst, binop(op, mkexpr(src1), mkexpr(off)));
> ++ break;
> ++ }
> ++ case 8:
> ++ assign(dst, binop(op, mkexpr(src), mkexpr(off)));
> ++ break;
> ++ default:
> ++ vpanic("dis_op3_assignSrc(amd64)");
> ++ }
> ++}
> ++
> ++/* XXX Insert unnecessary putIReG(). Because, in order to not be deleted
> ++ by optimization after here. */
> ++static void
> ++dis_op3_putIRegG(Int size, Prefix pfx, UChar modrm, IRTemp dst)
> ++{
> ++ switch (size) {
> ++ case 4:
> ++ putIRegG(size, pfx, modrm, unop(Iop_64to32, mkexpr(dst)));
> ++ break;
> ++ case 8:
> ++ putIRegG(size, pfx, modrm, mkexpr(dst));
> ++ break;
> ++ default:
> ++ vpanic("dis_op3_putIRegG(amd64)");
> ++ }
> ++}
> ++
> ++static
> ++Int dis_op3_G_S_E ( VexAbiInfo* vbi,
> ++ Prefix pfx,
> ++ IROp op,
> ++ Int size,
> ++ Long delta0,
> ++ /*OUT*/HChar* buf)
> ++{
> ++ IRType ty = szToITy(size);
> ++ IRTemp src = newTemp(ty);
> ++ IRTemp dst = newTemp(szToITy(8));
> ++ IRTemp off = newTemp(szToITy(8));
> ++ Long delta = delta0;
> ++ UChar modrm = getUChar(delta0++);
> ++ UChar rm = (modrm & 7);
> ++
> ++ if (rm == 0x4 || rm == 0x5) {
> ++ UChar sib = getUChar(delta0++);
> ++ UChar scale = toUChar((sib >> 6) & 3);
> ++ UChar index_r = toUChar((sib >> 3) & 7);
> ++ UChar base_r = toUChar(sib & 7);
> ++ if (scale == 0x00 && index_r == R_RSP && base_r == R_RBP) {
> ++ Long d = getSDisp32(delta0);
> ++ delta0 += 4;
> ++ assign(src, getIRegG(size,pfx,modrm));
> ++ assign(off, mkU64(d));
> ++ dis_op3_assignDst(op, size, src, dst, off);
> ++ dis_op3_putIRegG(size, pfx, modrm, dst);
> ++
> ++ DIS(buf, "%s%lld", segRegTxt(pfx), d);
> ++ return delta0 - delta;
> ++ }
> ++ }
> ++
> ++ vassert(size == 8); /* XXX 64bit only */
> ++ assign(src, getIRegG(size,pfx,modrm));
> ++ assign(off, getIRegE(size, pfx, modrm | 0xc0));
> ++ assign(dst, binop(op, mkexpr(src), mkexpr(off)));
> ++ dis_op3_putIRegG(size, pfx, modrm, dst);
> ++
> ++ DIS(buf, "%s(%s)", segRegTxt(pfx),
> ++ nameIRegRexB(haveASO(pfx) ? 4 : 8, pfx, rm));
> ++ return delta0 - delta;
> ++}
> ++#endif
> ++
> + /* Handle move instructions of the form
> + mov E, G meaning
> + mov reg-or-mem, reg
> +@@ -3173,6 +3312,15 @@ ULong dis_mov_E_G ( VexAbiInfo* vbi,
> +
> + /* E refers to memory */
> + {
> ++#if defined(__OpenBSD__)
> ++ if (haveFS(pfx)) {
> ++ len = dis_op3_S_G_E(vbi, pfx, Iop_MovFromSeg64, size, delta0,
> dis_buf);
> ++ DIP("mov%c %s,%s\n", nameISize(size),
> ++ dis_buf,
> ++ nameIRegG(size,pfx,rm));
> ++ return delta0+len;
> ++ }
> ++#endif
> + IRTemp addr = disAMode ( &len, vbi, pfx, delta0, dis_buf, 0 );
> + putIRegG(size, pfx, rm, loadLE(szToITy(size), mkexpr(addr)));
> + DIP("mov%c %s,%s\n", nameISize(size),
> +@@ -3213,6 +3361,16 @@ ULong dis_mov_G_E ( VexAbiInfo* vbi,
> +
> + *ok = True;
> +
> ++#if defined(__OpenBSD__)
> ++ if (haveFS(pfx)) {
> ++ len = dis_op3_G_S_E(vbi, pfx, Iop_MovToSeg64, size, delta0, dis_buf);
> ++ DIP("mov%c %s,%s\n", nameISize(size),
> ++ nameIRegG(size,pfx,rm),
> ++ dis_buf);
> ++ return delta0+len;
> ++ }
> ++#endif
> ++
> + if (epartIsReg(rm)) {
> + if (haveF2orF3(pfx)) { *ok = False; return delta0; }
> + putIRegE(size, pfx, rm, getIRegG(size, pfx, rm));
> Index: patches/patch-VEX_priv_host_amd64_defs_c
> ===================================================================
> RCS file: patches/patch-VEX_priv_host_amd64_defs_c
> diff -N patches/patch-VEX_priv_host_amd64_defs_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_host_amd64_defs_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,148 @@
> +--- VEX/priv/host_amd64_defs.c.orig
> ++++ VEX/priv/host_amd64_defs.c
> +@@ -1009,6 +1009,23 @@ AMD64Instr* AMD64Instr_ProfInc ( void ) {
> + i->tag = Ain_ProfInc;
> + return i;
> + }
> ++#if defined(__OpenBSD__)
> ++AMD64Instr* AMD64Instr_MovFromSeg64 ( HReg off, HReg dst ) {
> ++ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
> ++ i->tag = Ain_MovFromSeg64;
> ++ i->Ain.MovSeg.off = off;
> ++ i->Ain.MovSeg.dst = dst;
> ++ return i;
> ++}
> ++
> ++AMD64Instr* AMD64Instr_MovToSeg64 ( HReg src, HReg off ) {
> ++ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
> ++ i->tag = Ain_MovToSeg64;
> ++ i->Ain.MovSeg.src = src;
> ++ i->Ain.MovSeg.off = off;
> ++ return i;
> ++}
> ++#endif
> +
> + void ppAMD64Instr ( AMD64Instr* i, Bool mode64 )
> + {
> +@@ -1320,6 +1337,21 @@ void ppAMD64Instr ( AMD64Instr* i, Bool mode64 )
> + case Ain_ProfInc:
> + vex_printf("(profInc) movabsq $NotKnownYet, %%r11; incq (%%r11)");
> + return;
> ++#if defined(__OpenBSD__)
> ++ case Ain_MovFromSeg64:
> ++ vex_printf("addr32 mov fs:(");
> ++ ppHRegAMD64(i->Ain.MovSeg.off);
> ++ vex_printf("),");
> ++ ppHRegAMD64(i->Ain.MovSeg.dst);
> ++ return;
> ++ case Ain_MovToSeg64:
> ++ vex_printf("mov ");
> ++ ppHRegAMD64(i->Ain.MovSeg.src);
> ++ vex_printf(",fs:(");
> ++ ppHRegAMD64(i->Ain.MovSeg.off);
> ++ vex_printf("),");
> ++ return;
> ++#endif
> + default:
> + vpanic("ppAMD64Instr");
> + }
> +@@ -1625,6 +1657,16 @@ void getRegUsage_AMD64Instr ( HRegUsage* u,
> AMD64Instr* i, Bool mode64 )
> + case Ain_ProfInc:
> + addHRegUse(u, HRmWrite, hregAMD64_R11());
> + return;
> ++#if defined(__OpenBSD__)
> ++ case Ain_MovFromSeg64:
> ++ addHRegUse(u, HRmRead, i->Ain.MovSeg.off);
> ++ addHRegUse(u, HRmWrite, i->Ain.MovSeg.dst);
> ++ return;
> ++ case Ain_MovToSeg64:
> ++ addHRegUse(u, HRmRead, i->Ain.MovSeg.src);
> ++ addHRegUse(u, HRmWrite, i->Ain.MovSeg.off);
> ++ return;
> ++#endif
> + default:
> + ppAMD64Instr(i, mode64);
> + vpanic("getRegUsage_AMD64Instr");
> +@@ -1808,6 +1850,16 @@ void mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr*
> i, Bool mode64 )
> + case Ain_ProfInc:
> + /* hardwires r11 -- nothing to modify. */
> + return;
> ++#if defined(__OpenBSD__)
> ++ case Ain_MovFromSeg64:
> ++ mapReg(m, &i->Ain.MovSeg.off);
> ++ mapReg(m, &i->Ain.MovSeg.dst);
> ++ return;
> ++ case Ain_MovToSeg64:
> ++ mapReg(m, &i->Ain.MovSeg.src);
> ++ mapReg(m, &i->Ain.MovSeg.off);
> ++ return;
> ++#endif
> + default:
> + ppAMD64Instr(i, mode64);
> + vpanic("mapRegs_AMD64Instr");
> +@@ -3522,6 +3574,65 @@ Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc,
> + goto done;
> + }
> +
> ++#if defined(__OpenBSD__)
> ++ case Ain_MovFromSeg64: {
> ++ /* Following rm and reg are means r/m and reg of prefix ModR/M.
> ++ bit 7 6 5 4 3 2 1 0
> ++ +---+-----+-----+
> ++ mod| reg | r/m
> ++ */
> ++ UChar rm = 0;
> ++ UChar d_reg = 0;
> ++ *p++ = 0x64; /* Prefix of FS register */
> ++ *p++ = rexAMode_R( i->Ain.MovSeg.dst, i->Ain.MovSeg.off );
> ++ *p++ = 0x8b; /* Opcode of mov */
> ++ rm = hregNumber( i->Ain.MovSeg.off );
> ++ d_reg = hregNumber( i->Ain.MovSeg.dst );
> ++ switch (rm) {
> ++ case 4: /* rsp */
> ++ case 12: /* r12 */
> ++ *p++ = 0x4 | ((d_reg & 0x7) << 3);
> ++ *p++ = 0x24;
> ++ goto done;
> ++ case 5: /* rbp */
> ++ case 13: /* r13 */
> ++ *p++ = 0x45 | ((d_reg & 0x7) << 3);
> ++ *p++ = 0x00;
> ++ goto done;
> ++ }
> ++ rm = iregBits210( i->Ain.MovSeg.off );
> ++ d_reg = iregBits210( i->Ain.MovSeg.dst) << 3;
> ++ *p++ = rm | d_reg;
> ++ goto done;
> ++ }
> ++
> ++ case Ain_MovToSeg64: {
> ++ UChar rm = 0;
> ++ UChar s_reg = 0;
> ++ UChar o_reg = 0;
> ++ *p++ = 0x64; /* Prefix of FS register */
> ++ *p++ = rexAMode_R( i->Ain.MovSeg.src, i->Ain.MovSeg.off );
> ++ *p++ = 0x89; /* Opcode of mov */
> ++ rm = hregNumber( i->Ain.MovSeg.off );
> ++ o_reg = rm & 0x7;
> ++ s_reg = (hregNumber( i->Ain.MovSeg.src ) & 0x7) << 3;
> ++ switch (rm) {
> ++ case 4: /* rsp */
> ++ case 12: /* r12 */
> ++ *p++ = s_reg | o_reg;
> ++ *p++ = 0x24;
> ++ goto done;
> ++ case 5: /* rbp */
> ++ case 13: /* r13 */
> ++ *p++ = 0x40 | s_reg | o_reg;
> ++ *p++ = 0x00;
> ++ goto done;
> ++ }
> ++ *p++ = s_reg | o_reg;
> ++ goto done;
> ++ }
> ++#endif
> ++
> + default:
> + goto bad;
> + }
> Index: patches/patch-VEX_priv_host_amd64_defs_h
> ===================================================================
> RCS file: patches/patch-VEX_priv_host_amd64_defs_h
> diff -N patches/patch-VEX_priv_host_amd64_defs_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_host_amd64_defs_h 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,38 @@
> +--- VEX/priv/host_amd64_defs.h.orig
> ++++ VEX/priv/host_amd64_defs.h
> +@@ -403,6 +403,10 @@ typedef
> + //uu Ain_AvxReRg, /* AVX binary general reg-reg, Re, Rg */
> + Ain_EvCheck, /* Event check */
> + Ain_ProfInc /* 64-bit profile counter increment */
> ++#if defined(__OpenBSD__)
> ++ ,Ain_MovFromSeg64 /* 64-bit move sreg:(reg),reg */
> ++ ,Ain_MovToSeg64 /* 64-bit move sreg:(reg),reg */
> ++#endif
> + }
> + AMD64InstrTag;
> +
> +@@ -686,6 +690,13 @@ typedef
> + installed later, post-translation, by patching it in,
> + as it is not known at translation time. */
> + } ProfInc;
> ++#if defined(__OpenBSD__)
> ++ struct {
> ++ HReg src;
> ++ HReg off;
> ++ HReg dst;
> ++ } MovSeg;
> ++#endif
> +
> + } Ain;
> + }
> +@@ -744,6 +755,10 @@ extern AMD64Instr* AMD64Instr_SseShuf ( Int order,
> HReg src, HReg dst );
> + extern AMD64Instr* AMD64Instr_EvCheck ( AMD64AMode* amCounter,
> + AMD64AMode* amFailAddr );
> + extern AMD64Instr* AMD64Instr_ProfInc ( void );
> ++#if defined(__OpenBSD__)
> ++extern AMD64Instr* AMD64Instr_MovFromSeg64 ( HReg, HReg );
> ++extern AMD64Instr* AMD64Instr_MovToSeg64 ( HReg, HReg );
> ++#endif
> +
> +
> + extern void ppAMD64Instr ( AMD64Instr*, Bool );
> Index: patches/patch-VEX_priv_host_amd64_isel_c
> ===================================================================
> RCS file: patches/patch-VEX_priv_host_amd64_isel_c
> diff -N patches/patch-VEX_priv_host_amd64_isel_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_host_amd64_isel_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,25 @@
> +--- VEX/priv/host_amd64_isel.c.orig
> ++++ VEX/priv/host_amd64_isel.c
> +@@ -1369,6 +1369,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr*
> e )
> + return dst;
> + }
> +
> ++#if defined(__OpenBSD__)
> ++ if (e->Iex.Binop.op == Iop_MovFromSeg64) {
> ++ HReg dst = iselIntExpr_R(env, e->Iex.Binop.arg1);
> ++ HReg off = iselIntExpr_R(env, e->Iex.Binop.arg2);
> ++ addInstr(env, AMD64Instr_MovFromSeg64(off, dst));
> ++ return dst;
> ++ }
> ++
> ++ if (e->Iex.Binop.op == Iop_MovToSeg64) {
> ++ HReg src = iselIntExpr_R(env, e->Iex.Binop.arg1);
> ++ HReg off = iselIntExpr_R(env, e->Iex.Binop.arg2);
> ++ addInstr(env, AMD64Instr_MovToSeg64(src, off));
> ++ return src;
> ++ }
> ++#endif
> ++
> + break;
> + }
> +
> Index: patches/patch-VEX_priv_ir_defs_c
> ===================================================================
> RCS file: patches/patch-VEX_priv_ir_defs_c
> diff -N patches/patch-VEX_priv_ir_defs_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_priv_ir_defs_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,39 @@
> +--- VEX/priv/ir_defs.c.orig
> ++++ VEX/priv/ir_defs.c
> +@@ -1235,6 +1235,13 @@ void ppIROp ( IROp op )
> +
> + case Iop_PwBitMtxXpose64x2: vex_printf("BitMatrixTranspose64x2");
> return;
> +
> ++#if defined(__OpenBSD__)
> ++ case Iop_MovFromSeg8 ... Iop_MovFromSeg64:
> ++ str = "MovFromSeg"; base = Iop_MovFromSeg8; break;
> ++ case Iop_MovToSeg8 ... Iop_MovToSeg64:
> ++ str = "MovToSeg"; base = Iop_MovToSeg8; break;
> ++#endif
> ++
> + default: vpanic("ppIROp(1)");
> + }
> +
> +@@ -2480,7 +2487,9 @@ void typeOfPrimop ( IROp op,
> + switch (op) {
> + case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
> + case Iop_Or8: case Iop_And8: case Iop_Xor8:
> ++#if defined(__OpenBSD__)
> + BINARY(Ity_I8,Ity_I8, Ity_I8);
> ++#endif
> +
> + case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
> + case Iop_Or16: case Iop_And16: case Iop_Xor16:
> +@@ -3391,6 +3400,12 @@ void typeOfPrimop ( IROp op,
> + case Iop_SarN16x16: case Iop_SarN32x8:
> + BINARY(Ity_V256,Ity_I8, Ity_V256);
> +
> ++#if defined(__OpenBSD__)
> ++ case Iop_MovFromSeg64:
> ++ case Iop_MovToSeg64:
> ++ BINARY( Ity_I64, Ity_I64, Ity_I64 );
> ++#endif
> ++
> + default:
> + ppIROp(op);
> + vpanic("typeOfPrimop");
> Index: patches/patch-VEX_pub_libvex_ir_h
> ===================================================================
> RCS file: patches/patch-VEX_pub_libvex_ir_h
> diff -N patches/patch-VEX_pub_libvex_ir_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-VEX_pub_libvex_ir_h 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,14 @@
> +--- VEX/pub/libvex_ir.h.orig
> ++++ VEX/pub/libvex_ir.h
> +@@ -1815,6 +1815,11 @@ typedef
> + Iop_RSqrtEst32Fx8,
> + Iop_RecipEst32Fx8,
> +
> ++#if defined(__OpenBSD__)
> ++ Iop_MovFromSeg8, Iop_MovFromSeg16, Iop_MovFromSeg32, Iop_MovFromSeg64,
> ++ Iop_MovToSeg8, Iop_MovToSeg16, Iop_MovToSeg32, Iop_MovToSeg64,
> ++#endif
> ++
> + Iop_Max32Fx8, Iop_Min32Fx8,
> + Iop_Max64Fx4, Iop_Min64Fx4,
> + Iop_LAST /* must be the last enumerator */
> Index: patches/patch-coregrind_link_tool_exe_openbsd_in
> ===================================================================
> RCS file: patches/patch-coregrind_link_tool_exe_openbsd_in
> diff -N patches/patch-coregrind_link_tool_exe_openbsd_in
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_link_tool_exe_openbsd_in 27 Sep 2019 03:08:46
> -0000
> @@ -0,0 +1,16 @@
> +--- coregrind/link_tool_exe_openbsd.in.orig Fri Sep 27 10:40:06 2019
> ++++ coregrind/link_tool_exe_openbsd.in Fri Sep 27 10:45:59 2019
> +@@ -77,7 +77,12 @@
> + my $origbase = 0x400000;
> + system(sprintf "sed -e 's|%x|%x|g' < $ldscript > $temp", $origbase,
> $notebase);
> +
> +-my $cmd = sprintf "$cc -static -nopie -Wl,-Ttext=0x%x -Wl,-T,$temp",
> $textbase;
> ++my $cmd = sprintf "$cc -static -nopie -Wl,--strip-all -Wl,-zwxneeded
> -Wl,-Ttext=0x%x -Wl,-T,$temp", $textbase;
> ++# XXX The '-s' option was not specified when executing the install command.
> ++# Instead '--strip-all' is now executed at link time.
> ++# strip command rewrite offset and align in ELF file. Therefor, when
> valgrind
> ++# launch memcheck-amd64-openbsd, an Abort trap occurs in the execvp() system
> ++# call.
> +
> + # Add the rest of the parameters
> + foreach my $n (2 .. $#ARGV) {
> Index: patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> diff -N patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c 27 Sep 2019
> 03:08:46 -0000
> @@ -0,0 +1,14 @@
> +--- coregrind/m_aspacemgr/aspacemgr-common.c.orig
> ++++ coregrind/m_aspacemgr/aspacemgr-common.c
> +@@ -458,7 +458,11 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp
> )
> + szB = VG_STACK_GUARD_SZB
> + + VG_STACK_ACTIVE_SZB + VG_STACK_GUARD_SZB;
> +
> ++#if defined(__OpenBSD__)
> ++ sres = VG_(am_mmap_anon_float_valgrind_stack)( szB );
> ++#else
> + sres = VG_(am_mmap_anon_float_valgrind)( szB );
> ++#endif
> + if (sr_isError(sres))
> + return NULL;
> +
> Index: patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> diff -N patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c 27 Sep 2019
> 03:08:46 -0000
> @@ -0,0 +1,57 @@
> +--- coregrind/m_aspacemgr/aspacemgr-linux.c.orig
> ++++ coregrind/m_aspacemgr/aspacemgr-linux.c
> +@@ -2543,6 +2543,54 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length
> )
> + return sres;
> + }
> +
> ++#if defined(__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_PROT_EXEC,
> ++ 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). */
> +
> + void* VG_(am_shadow_alloc)(SizeT size)
> Index: patches/patch-coregrind_m_debuglog_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_debuglog_c
> diff -N patches/patch-coregrind_m_debuglog_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_debuglog_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,14 @@
> +--- coregrind/m_debuglog.c.orig
> ++++ coregrind/m_debuglog.c
> +@@ -470,7 +470,11 @@ static UInt local_sys_write_stderr ( HChar* buf, Int n )
> + __asm__ volatile (
> + "subq $256, %%rsp\n" /* don't trash the stack redzone */
> + "pushq %%r15\n" /* r15 is callee-save */
> ++#if __clang_major__ >= 6
> ++ "lea %0, %%r15\n" /* r15 = &block */
> ++#else
> + "movq %0, %%r15\n" /* r15 = &block */
> ++#endif
> + "pushq %%r15\n" /* save &block */
> + "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" /* rax = __NR_write */
> + "movq $2, %%rdi\n" /* rdi = stderr */
> Index: patches/patch-coregrind_m_libcproc_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_libcproc_c
> diff -N patches/patch-coregrind_m_libcproc_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_libcproc_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,16 @@
> +--- coregrind/m_libcproc.c.orig
> ++++ coregrind/m_libcproc.c
> +@@ -1033,6 +1033,13 @@ void VG_(flush_dcache) ( void *ptr, SizeT nbytes )
> + # endif
> + }
> +
> ++#if defined(__OpenBSD__)
> ++void VG_(__set_tcb)(void *tcb)
> ++{
> ++ (void)VG_(do_syscall1)(__NR___set_tcb, tcb);
> ++}
> ++#endif
> ++
> + /*--------------------------------------------------------------------*/
> + /*--- end ---*/
> + /*--------------------------------------------------------------------*/
> Index: patches/patch-coregrind_m_main_c
> ===================================================================
> RCS file: /cvs/ports/devel/valgrind/patches/patch-coregrind_m_main_c,v
> retrieving revision 1.2
> diff -u -p -r1.2 patch-coregrind_m_main_c
> --- patches/patch-coregrind_m_main_c 4 Feb 2019 23:34:10 -0000 1.2
> +++ patches/patch-coregrind_m_main_c 27 Sep 2019 03:08:46 -0000
> @@ -6,16 +6,101 @@ https://bitbucket.org/uebayasi/valgrind-
> Index: coregrind/m_main.c
> --- coregrind/m_main.c.orig
> +++ coregrind/m_main.c
> -@@ -1725,7 +1725,9 @@ Int valgrind_main ( Int argc, HChar **argv, HChar **en
> +@@ -1524,7 +1524,38 @@
> +
> + /* --- end of Forwards decls to do with shutdown --- */
> +
> ++#if defined(__OpenBSD__)
> ++#include <tib.h>
> +
> ++#define ELF_ROUND(x,malign) (((x) + (malign)-1) & ~((malign)-1))
> ++
> ++extern void setup_static_tib(void);
> ++
> ++void
> ++setup_static_tib(void)
> ++{
> ++ struct tib *tib;
> ++ char *base;
> ++ SysRes sres;
> ++ SizeT size;
> ++
> ++ size = ELF_ROUND(0 + sizeof *tib, 4096);
> ++ sres = VG_(am_mmap_anon_float_valgrind)(size);
> ++ if (sr_isError(sres)) {
> ++ VG_(out_of_memory_NORETURN)("TIB", size);
> ++ /*NOTREACHED*/
> ++ }
> ++ base = (char *)(AddrH)sr_Res(sres);
> ++
> ++ tib = (struct tib *)base;
> ++
> ++ TIB_INIT(tib, NULL, NULL);
> ++ tib->tib_tid = VG_(gettid)();
> ++
> ++ VG_(__set_tcb)(TIB_TO_TCB(tib));
> ++}
> ++#endif
> ++
> + /* By the time we get to valgrind_main, the_iicii should already have
> + been filled in with any important details as required by whatever
> + OS we have been built for.
> +@@ -1612,6 +1643,7 @@
> + // Ensure we're on a plausible stack.
> + // p: logging
> + //--------------------------------------------------------------
> ++#if !defined(__OpenBSD__)
> + VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
> + { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
> + HChar* limHi = limLo + sizeof(VG_(interim_stack));
> +@@ -1643,6 +1675,7 @@
> + VG_(exit)(1);
> + }
> + }
> ++#endif
> +
> + //--------------------------------------------------------------
> + // Ensure we have a plausible pointer to the stack on which
> +@@ -1725,7 +1758,9 @@
> // child processes will have a reasonable brk value.
> VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
> zero.rlim_max = VG_(client_rlimit_data).rlim_max;
> -+#if 0
> ++#if !defined(__OpenBSD__)
> VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
> +#endif
>
> // Get the current process stack rlimit.
> VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
> +@@ -2433,6 +2468,10 @@
> + VG_(address_of_m_main_shutdown_actions_NORETURN)
> + = & shutdown_actions_NORETURN;
> +
> ++#if defined(__OpenBSD__)
> ++ setup_static_tib();
> ++#endif
> ++
> + /* Run the first thread, eventually ending up at the continuation
> + address. */
> + VG_(main_thread_wrapper_NORETURN)(1);
> +@@ -3159,6 +3198,8 @@
> + "__start:\n"
> + /* pass args (long argc, char **argv, ...) on stack */
> + "\tmovq %rsp, %rdi\n"
> ++#if !defined(__OpenBSD__)
> ++ /* OpenBSD 6.4 and later can not use BBS for stack area */
> + /* set up the new stack in %rsi */
> + "\tmovq $vgPlain_interim_stack, %rsi\n"
> + "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rsi\n"
> +@@ -3166,6 +3207,9 @@
> + "\tandq $~15, %rsi\n"
> + /* install it, and collect the original one */
> + "\txchgq %rsi, %rsp\n"
> ++#else
> ++ "\tmov %rsp, %rsi\n"
> ++#endif
> + /* call _start_in_C_amd64_freebsd, passing it the startup %rsp */
> + "\tcall _start_in_C_amd64_openbsd\n"
> + "\thlt\n"
> @@ -3233,7 +3235,7 @@ __asm(" .section \".note.openbsd.ident\", \"a\"\n"
> #if !defined(VGO_openbsd)
> #include <elf.h>
> Index: patches/patch-coregrind_m_scheduler_scheduler_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_scheduler_scheduler_c
> diff -N patches/patch-coregrind_m_scheduler_scheduler_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_scheduler_scheduler_c 27 Sep 2019 03:08:46
> -0000
> @@ -0,0 +1,74 @@
> +--- coregrind/m_scheduler/scheduler.c.orig
> ++++ coregrind/m_scheduler/scheduler.c
> +@@ -854,6 +854,9 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> + volatile ThreadState* tst = NULL; /* stop gcc complaining */
> + volatile Int done_this_time = 0;
> + volatile HWord host_code_addr = 0;
> ++#if defined(__OpenBSD__)
> ++ volatile UInt host_code_len = 0;
> ++#endif
> +
> + /* Paranoia */
> + vg_assert(VG_(is_valid_tid)(tid));
> +@@ -879,8 +882,15 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> + } else {
> + /* normal case -- redir translation */
> + UInt cno = (UInt)VG_TT_FAST_HASH((Addr)tst->arch.vex.VG_INSTR_PTR);
> ++#if defined(__OpenBSD__)
> ++ if (LIKELY(VG_(tt_fast)[cno].guest ==
> (Addr)tst->arch.vex.VG_INSTR_PTR)) {
> ++ host_code_addr = VG_(tt_fast)[cno].host;
> ++ host_code_len = VG_(tt_fast)[cno].len;
> ++ }
> ++#else
> + if (LIKELY(VG_(tt_fast)[cno].guest ==
> (Addr)tst->arch.vex.VG_INSTR_PTR))
> + host_code_addr = VG_(tt_fast)[cno].host;
> ++#endif
> + else {
> + AddrH res = 0;
> + /* not found in VG_(tt_fast). Searching here the transtab
> +@@ -932,6 +942,22 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> + vg_assert(VG_(in_generated_code) == False);
> + VG_(in_generated_code) = True;
> +
> ++#if defined(__OpenBSD__)
> ++ if (host_code_len > 0) {
> ++ SysRes sres;
> ++
> ++ /* Protect the guard areas. */
> ++ sres = VG_(am_do_mprotect_NO_NOTIFY)(
> ++ host_code_addr, host_code_len,
> ++ VKI_PROT_READ | VKI_PROT_EXEC
> ++ );
> ++ if (sr_isError(sres)) {
> ++ VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
> ++ vg_assert(0);
> ++ }
> ++ }
> ++#endif
> ++
> + SCHEDSETJMP(
> + tid,
> + jumped,
> +@@ -942,6 +968,22 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> + )
> + );
> +
> ++#if defined(__OpenBSD__)
> ++ if (host_code_len > 0) {
> ++ SysRes sres;
> ++
> ++ /* Protect the guard areas. */
> ++ sres = VG_(am_do_mprotect_NO_NOTIFY)(
> ++ host_code_addr, host_code_len,
> ++ VKI_PROT_READ | VKI_PROT_WRITE | VKI_PROT_EXEC
> ++ );
> ++ if (sr_isError(sres)) {
> ++ VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
> ++ vg_assert(0);
> ++ }
> ++ }
> ++#endif
> ++
> + vg_assert(VG_(in_generated_code) == True);
> + VG_(in_generated_code) = False;
> +
> Index: patches/patch-coregrind_m_transtab_c
> ===================================================================
> RCS file: patches/patch-coregrind_m_transtab_c
> diff -N patches/patch-coregrind_m_transtab_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_m_transtab_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,60 @@
> +--- coregrind/m_transtab.c.orig Wed Nov 26 04:41:21 2014
> ++++ coregrind/m_transtab.c Mon Dec 10 17:05:02 2018
> +@@ -1322,11 +1321,18 @@
> + return k32 % N_TTES_PER_SECTOR;
> + }
> +
> ++#if defined(__OpenBSD__)
> ++static void setFastCacheEntry ( Addr64 key, ULong* tcptr, UInt len )
> ++#else
> + static void setFastCacheEntry ( Addr64 key, ULong* tcptr )
> ++#endif
> + {
> + UInt cno = (UInt)VG_TT_FAST_HASH(key);
> + VG_(tt_fast)[cno].guest = (Addr)key;
> + VG_(tt_fast)[cno].host = (Addr)tcptr;
> ++#if defined(__OpenBSD__)
> ++ VG_(tt_fast)[cno].len = (Addr)len;
> ++#endif
> + n_fast_updates++;
> + /* This shouldn't fail. It should be assured by m_translate
> + which should reject any attempt to make translation of code
> +@@ -1670,7 +1676,11 @@
> + }
> +
> + /* Update the fast-cache. */
> ++#if defined(__OpenBSD__)
> ++ setFastCacheEntry( entry, tcptr, code_len );
> ++#else
> + setFastCacheEntry( entry, tcptr );
> ++#endif
> +
> + /* Note the eclass numbers for this translation. */
> + upd_eclasses_after_add( §ors[y], i );
> +@@ -1712,8 +1722,13 @@
> + && sectors[sno].tt[k].entry == guest_addr) {
> + /* found it */
> + if (upd_cache)
> ++#if defined(__OpenBSD__)
> ++ setFastCacheEntry(
> ++ guest_addr, sectors[sno].tt[k].tcptr, 0 );
> ++#else
> + setFastCacheEntry(
> + guest_addr, sectors[sno].tt[k].tcptr );
> ++#endif
> + if (res_hcode)
> + *res_hcode = (AddrH)sectors[sno].tt[k].tcptr;
> + if (res_sNo)
> +@@ -2204,7 +2219,12 @@
> + vg_assert(sizeof(Addr64) == 8);
> + /* check fast cache entries really are 2 words long */
> + vg_assert(sizeof(Addr) == sizeof(void*));
> ++#if defined(__OpenBSD__)
> ++ vg_assert(sizeof(FastCacheEntry) ==
> ++ (2 * sizeof(Addr) + (2 * sizeof (UInt))));
> ++#else
> + vg_assert(sizeof(FastCacheEntry) == 2 * sizeof(Addr));
> ++#endif
> + /* check fast cache entries are packed back-to-back with no spaces */
> + vg_assert(sizeof( VG_(tt_fast) ) == VG_TT_FAST_SIZE *
> sizeof(FastCacheEntry));
> + /* check fast cache is aligned as we requested. Not fatal if it
> Index: patches/patch-coregrind_pub_core_aspacemgr_h
> ===================================================================
> RCS file: patches/patch-coregrind_pub_core_aspacemgr_h
> diff -N patches/patch-coregrind_pub_core_aspacemgr_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_pub_core_aspacemgr_h 27 Sep 2019 03:08:46
> -0000
> @@ -0,0 +1,13 @@
> +--- coregrind/pub_core_aspacemgr.h.orig
> ++++ coregrind/pub_core_aspacemgr.h
> +@@ -242,6 +242,9 @@ extern SysRes VG_(am_mmap_anon_float_client) ( SizeT
> length,
> + Int prot );
> + segment array accordingly. This is fundamentally how V allocates
> + itself more address space when needed. */
> + extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
> ++#if defined(__OpenBSD__)
> ++extern SysRes VG_(am_mmap_anon_float_valgrind_stack)( SizeT cszB );
> ++#endif
> +
> + /* Map privately a file at an unconstrained address for V, and update the
> + segment array accordingly. This is used by V for transiently
> Index: patches/patch-coregrind_pub_core_transtab_h
> ===================================================================
> RCS file: patches/patch-coregrind_pub_core_transtab_h
> diff -N patches/patch-coregrind_pub_core_transtab_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-coregrind_pub_core_transtab_h 27 Sep 2019 03:08:46
> -0000
> @@ -0,0 +1,12 @@
> +--- coregrind/pub_core_transtab.h.orig
> ++++ coregrind/pub_core_transtab.h
> +@@ -45,6 +45,9 @@ typedef
> + struct {
> + Addr guest;
> + Addr host;
> ++#if defined(__OpenBSD__)
> ++ UInt len;
> ++#endif
> + }
> + FastCacheEntry;
> +
> Index: patches/patch-include_vki_vki-openbsd_h
> ===================================================================
> RCS file: patches/patch-include_vki_vki-openbsd_h
> diff -N patches/patch-include_vki_vki-openbsd_h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-include_vki_vki-openbsd_h 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,13 @@
> +--- include/vki/vki-openbsd.h.orig
> ++++ include/vki/vki-openbsd.h
> +@@ -1544,9 +1544,9 @@
> + #define VKI_MAP_PRIVATE 0x02 /* Changes are private */
> + #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */
> + #define VKI_MAP_NORESERVE 0x0040 /* don't check for reservations
> */
> +-#define VKI_MAP_STACK 0x400
> + #define VKI_MAP_ANON 0x1000 /* don't use a file */
> + #define VKI_MAP_ANONYMOUS VKI_MAP_ANON
> ++#define VKI_MAP_STACK 0x4000
> +
> + //----------------------------------------------------------------------
> + // From sys/stat.h
> Index: patches/patch-memcheck_mc_translate_c
> ===================================================================
> RCS file: patches/patch-memcheck_mc_translate_c
> diff -N patches/patch-memcheck_mc_translate_c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-memcheck_mc_translate_c 27 Sep 2019 03:08:46 -0000
> @@ -0,0 +1,15 @@
> +--- memcheck/mc_translate.c.orig
> ++++ memcheck/mc_translate.c
> +@@ -4222,6 +4222,12 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
> + binop(Iop_V128HLtoV256, qV, shV));
> + }
> +
> ++#if defined(__OpenBSD__)
> ++ case Iop_MovFromSeg64:
> ++ case Iop_MovToSeg64:
> ++ return assignNew('V', mce, Ity_I64, binop(op, atom1, atom2));
> ++#endif
> ++
> + default:
> + ppIROp(op);
> + VG_(tool_panic)("memcheck:expr2vbits_Binop");
> --
> ASOU Masato
>
> From: Masato Asou <[email protected]>
> Date: Fri, 27 Sep 2019 13:18:50 +0900 (JST)
>
> > Hi ports,
> >
> > This is a patch for running valgrind memcheck on amd64. I corrected
> > the following two problems.
> >
> > - FS register can be used.
> > - Fixed a problem that strip command rewrites offset and align of
> > memcheck ELF file.
> >
> > Index: Makefile
> > ===================================================================
> > RCS file: /cvs/ports/devel/valgrind/Makefile,v
> > retrieving revision 1.19
> > diff -u -p -r1.19 Makefile
> > --- Makefile 12 Jul 2019 20:46:03 -0000 1.19
> > +++ Makefile 27 Sep 2019 03:08:46 -0000
> > @@ -38,4 +38,10 @@ AUTORECONF = /bin/sh ./autogen.sh
> > .if ${PROPERTIES:Mclang}
> > # replace -lgcc
> > MAKE_FLAGS = TOOL_LDADD_COMMON=-lcompiler_rt
> > +# XXX The '-s' option was not specified when executing the install command.
> > +# Instead '--strip-all' is now executed at link time.
> > +# strip command rewrite offset and align in ELF file. Therefor, when
> > valgrind
> > +# launch memcheck-amd64-openbsd, an Abort trap occurs in the execvp()
> > system
> > +# call.
> > +INSTALL_STRIP =
> > .endif
> > Index: patches/patch-VEX_priv_guest_amd64_helpers_c
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_guest_amd64_helpers_c
> > diff -N patches/patch-VEX_priv_guest_amd64_helpers_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_guest_amd64_helpers_c 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,16 @@
> > +--- VEX/priv/guest_amd64_helpers.c.orig
> > ++++ VEX/priv/guest_amd64_helpers.c
> > +@@ -3744,6 +3744,13 @@ void LibVEX_GuestAMD64_initialise (
> > /*OUT*/VexGuestAMD64State* vex_state )
> > + /* HACK: represent the offset associated with %fs==0. This
> > + assumes that %fs is only ever zero. */
> > + vex_state->guest_FS_ZERO = 0;
> > ++#if defined(__OpenBSD__)
> > ++{
> > ++ int fs;
> > ++ __asm__("mov %%fs,%0" : "=r" (fs));
> > ++ vex_state->guest_FS_ZERO = fs;
> > ++}
> > ++#endif
> > +
> > + vex_state->guest_RIP = 0;
> > +
> > Index: patches/patch-VEX_priv_guest_amd64_toIR_c
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_guest_amd64_toIR_c
> > diff -N patches/patch-VEX_priv_guest_amd64_toIR_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_guest_amd64_toIR_c 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,205 @@
> > +--- VEX/priv/guest_amd64_toIR.c.orig
> > ++++ VEX/priv/guest_amd64_toIR.c
> > +@@ -312,7 +312,11 @@ static IROp mkSizedOp ( IRType ty, IROp op8 )
> > + || op8 == Iop_Shl8 || op8 == Iop_Shr8 || op8 == Iop_Sar8
> > + || op8 == Iop_CmpEQ8 || op8 == Iop_CmpNE8
> > + || op8 == Iop_CasCmpNE8
> > ++#if !defined(__OpenBSD__)
> > + || op8 == Iop_Not8 );
> > ++#else
> > ++ || op8 == Iop_Not8 || op8 == Iop_MovFromSeg8);
> > ++#endif
> > + switch (ty) {
> > + case Ity_I8: return 0 +op8;
> > + case Ity_I16: return 1 +op8;
> > +@@ -709,6 +713,12 @@ static Bool haveF3 ( Prefix pfx ) {
> > + return toBool((pfx & PFX_F3) > 0);
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++static Bool haveFS( Prefix pfx ) {
> > ++ return toBool((pfx & PFX_FS) > 0);
> > ++}
> > ++#endif
> > ++
> > + static Bool have66 ( Prefix pfx ) {
> > + return toBool((pfx & PFX_66) > 0);
> > + }
> > +@@ -1213,7 +1223,6 @@ static void putIRegRexB ( Int sz, Prefix pfx, UInt
> > lo3bits, IRExpr* e )
> > + ));
> > + }
> > +
> > +-
> > + /* Functions for getting register numbers from modrm bytes and REX
> > + when we don't have to consider the complexities of integer subreg
> > + accesses.
> > +@@ -3137,6 +3146,136 @@ ULong dis_op2_G_E ( VexAbiInfo* vbi,
> > + }
> > +
> > +
> > ++#if defined(__OpenBSD__)
> > ++/* Handle binary integer instructions of the form
> > ++ op S, G, E meaning
> > ++ op segment reg, reg, reg
> > ++ Is passed the a ptr to the modRM byte, the actual operation, and the
> > ++ data size. Returns the address advanced completely over this
> > ++ instruction.
> > ++
> > ++ S(segment) is reg.
> > ++ G(src) is reg.
> > ++
> > ++ OP %S:%G, tmp
> > ++ PUT tmp, %E
> > ++*/
> > ++static
> > ++Int dis_op3_S_G_E ( VexAbiInfo* vbi,
> > ++ Prefix pfx,
> > ++ IROp op,
> > ++ Int size,
> > ++ Long delta0,
> > ++ /*OUT*/HChar* buf)
> > ++{
> > ++ IRType ty = szToITy(size);
> > ++ IRTemp dst1 = newTemp(ty);
> > ++ IRTemp off = newTemp(ty);
> > ++ IRTemp dst0 = newTemp(ty);
> > ++ Long delta = delta0;
> > ++ UChar modrm = getUChar(delta0++);
> > ++ UChar rm = (modrm & 7);
> > ++
> > ++ assign(dst0, getIRegG(size, pfx, modrm));
> > ++ assign(off, getIRegE(size, pfx, modrm | 0xc0));
> > ++ assign(dst1, binop(op, mkexpr(dst0), mkexpr(off)));
> > ++ putIRegG(size, pfx, modrm, mkexpr(dst1));
> > ++
> > ++ if (rm == 0x4) {
> > ++ UChar tmp = getUChar(delta0++);
> > ++ vassert(tmp == 0x24);
> > ++ } else if (rm == 0x05) {
> > ++ UChar tmp = getUChar(delta0++);
> > ++ vassert(tmp == 0x00);
> > ++ }
> > ++
> > ++ DIS(buf, "%s(%s)", segRegTxt(pfx),
> > ++ nameIRegRexB(haveASO(pfx) ? 4 : 8, pfx, rm));
> > ++
> > ++ return delta0 - delta;
> > ++}
> > ++
> > ++static void
> > ++dis_op3_assignDst(IROp op, Int size, IRTemp src, IRTemp dst, IRTemp off)
> > ++{
> > ++ switch (size) {
> > ++ case 4: {
> > ++ IRTemp src1 = newTemp(szToITy(8));
> > ++ assign(src1, unop(Iop_32Uto64, mkexpr(src)));
> > ++ assign(dst, binop(op, mkexpr(src1), mkexpr(off)));
> > ++ break;
> > ++ }
> > ++ case 8:
> > ++ assign(dst, binop(op, mkexpr(src), mkexpr(off)));
> > ++ break;
> > ++ default:
> > ++ vpanic("dis_op3_assignSrc(amd64)");
> > ++ }
> > ++}
> > ++
> > ++/* XXX Insert unnecessary putIReG(). Because, in order to not be deleted
> > ++ by optimization after here. */
> > ++static void
> > ++dis_op3_putIRegG(Int size, Prefix pfx, UChar modrm, IRTemp dst)
> > ++{
> > ++ switch (size) {
> > ++ case 4:
> > ++ putIRegG(size, pfx, modrm, unop(Iop_64to32, mkexpr(dst)));
> > ++ break;
> > ++ case 8:
> > ++ putIRegG(size, pfx, modrm, mkexpr(dst));
> > ++ break;
> > ++ default:
> > ++ vpanic("dis_op3_putIRegG(amd64)");
> > ++ }
> > ++}
> > ++
> > ++static
> > ++Int dis_op3_G_S_E ( VexAbiInfo* vbi,
> > ++ Prefix pfx,
> > ++ IROp op,
> > ++ Int size,
> > ++ Long delta0,
> > ++ /*OUT*/HChar* buf)
> > ++{
> > ++ IRType ty = szToITy(size);
> > ++ IRTemp src = newTemp(ty);
> > ++ IRTemp dst = newTemp(szToITy(8));
> > ++ IRTemp off = newTemp(szToITy(8));
> > ++ Long delta = delta0;
> > ++ UChar modrm = getUChar(delta0++);
> > ++ UChar rm = (modrm & 7);
> > ++
> > ++ if (rm == 0x4 || rm == 0x5) {
> > ++ UChar sib = getUChar(delta0++);
> > ++ UChar scale = toUChar((sib >> 6) & 3);
> > ++ UChar index_r = toUChar((sib >> 3) & 7);
> > ++ UChar base_r = toUChar(sib & 7);
> > ++ if (scale == 0x00 && index_r == R_RSP && base_r == R_RBP) {
> > ++ Long d = getSDisp32(delta0);
> > ++ delta0 += 4;
> > ++ assign(src, getIRegG(size,pfx,modrm));
> > ++ assign(off, mkU64(d));
> > ++ dis_op3_assignDst(op, size, src, dst, off);
> > ++ dis_op3_putIRegG(size, pfx, modrm, dst);
> > ++
> > ++ DIS(buf, "%s%lld", segRegTxt(pfx), d);
> > ++ return delta0 - delta;
> > ++ }
> > ++ }
> > ++
> > ++ vassert(size == 8); /* XXX 64bit only */
> > ++ assign(src, getIRegG(size,pfx,modrm));
> > ++ assign(off, getIRegE(size, pfx, modrm | 0xc0));
> > ++ assign(dst, binop(op, mkexpr(src), mkexpr(off)));
> > ++ dis_op3_putIRegG(size, pfx, modrm, dst);
> > ++
> > ++ DIS(buf, "%s(%s)", segRegTxt(pfx),
> > ++ nameIRegRexB(haveASO(pfx) ? 4 : 8, pfx, rm));
> > ++ return delta0 - delta;
> > ++}
> > ++#endif
> > ++
> > + /* Handle move instructions of the form
> > + mov E, G meaning
> > + mov reg-or-mem, reg
> > +@@ -3173,6 +3312,15 @@ ULong dis_mov_E_G ( VexAbiInfo* vbi,
> > +
> > + /* E refers to memory */
> > + {
> > ++#if defined(__OpenBSD__)
> > ++ if (haveFS(pfx)) {
> > ++ len = dis_op3_S_G_E(vbi, pfx, Iop_MovFromSeg64, size, delta0,
> > dis_buf);
> > ++ DIP("mov%c %s,%s\n", nameISize(size),
> > ++ dis_buf,
> > ++ nameIRegG(size,pfx,rm));
> > ++ return delta0+len;
> > ++ }
> > ++#endif
> > + IRTemp addr = disAMode ( &len, vbi, pfx, delta0, dis_buf, 0 );
> > + putIRegG(size, pfx, rm, loadLE(szToITy(size), mkexpr(addr)));
> > + DIP("mov%c %s,%s\n", nameISize(size),
> > +@@ -3213,6 +3361,16 @@ ULong dis_mov_G_E ( VexAbiInfo* vbi,
> > +
> > + *ok = True;
> > +
> > ++#if defined(__OpenBSD__)
> > ++ if (haveFS(pfx)) {
> > ++ len = dis_op3_G_S_E(vbi, pfx, Iop_MovToSeg64, size, delta0,
> > dis_buf);
> > ++ DIP("mov%c %s,%s\n", nameISize(size),
> > ++ nameIRegG(size,pfx,rm),
> > ++ dis_buf);
> > ++ return delta0+len;
> > ++ }
> > ++#endif
> > ++
> > + if (epartIsReg(rm)) {
> > + if (haveF2orF3(pfx)) { *ok = False; return delta0; }
> > + putIRegE(size, pfx, rm, getIRegG(size, pfx, rm));
> > Index: patches/patch-VEX_priv_host_amd64_defs_c
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_host_amd64_defs_c
> > diff -N patches/patch-VEX_priv_host_amd64_defs_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_host_amd64_defs_c 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,148 @@
> > +--- VEX/priv/host_amd64_defs.c.orig
> > ++++ VEX/priv/host_amd64_defs.c
> > +@@ -1009,6 +1009,23 @@ AMD64Instr* AMD64Instr_ProfInc ( void ) {
> > + i->tag = Ain_ProfInc;
> > + return i;
> > + }
> > ++#if defined(__OpenBSD__)
> > ++AMD64Instr* AMD64Instr_MovFromSeg64 ( HReg off, HReg dst ) {
> > ++ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
> > ++ i->tag = Ain_MovFromSeg64;
> > ++ i->Ain.MovSeg.off = off;
> > ++ i->Ain.MovSeg.dst = dst;
> > ++ return i;
> > ++}
> > ++
> > ++AMD64Instr* AMD64Instr_MovToSeg64 ( HReg src, HReg off ) {
> > ++ AMD64Instr* i = LibVEX_Alloc(sizeof(AMD64Instr));
> > ++ i->tag = Ain_MovToSeg64;
> > ++ i->Ain.MovSeg.src = src;
> > ++ i->Ain.MovSeg.off = off;
> > ++ return i;
> > ++}
> > ++#endif
> > +
> > + void ppAMD64Instr ( AMD64Instr* i, Bool mode64 )
> > + {
> > +@@ -1320,6 +1337,21 @@ void ppAMD64Instr ( AMD64Instr* i, Bool mode64 )
> > + case Ain_ProfInc:
> > + vex_printf("(profInc) movabsq $NotKnownYet, %%r11; incq
> > (%%r11)");
> > + return;
> > ++#if defined(__OpenBSD__)
> > ++ case Ain_MovFromSeg64:
> > ++ vex_printf("addr32 mov fs:(");
> > ++ ppHRegAMD64(i->Ain.MovSeg.off);
> > ++ vex_printf("),");
> > ++ ppHRegAMD64(i->Ain.MovSeg.dst);
> > ++ return;
> > ++ case Ain_MovToSeg64:
> > ++ vex_printf("mov ");
> > ++ ppHRegAMD64(i->Ain.MovSeg.src);
> > ++ vex_printf(",fs:(");
> > ++ ppHRegAMD64(i->Ain.MovSeg.off);
> > ++ vex_printf("),");
> > ++ return;
> > ++#endif
> > + default:
> > + vpanic("ppAMD64Instr");
> > + }
> > +@@ -1625,6 +1657,16 @@ void getRegUsage_AMD64Instr ( HRegUsage* u,
> > AMD64Instr* i, Bool mode64 )
> > + case Ain_ProfInc:
> > + addHRegUse(u, HRmWrite, hregAMD64_R11());
> > + return;
> > ++#if defined(__OpenBSD__)
> > ++ case Ain_MovFromSeg64:
> > ++ addHRegUse(u, HRmRead, i->Ain.MovSeg.off);
> > ++ addHRegUse(u, HRmWrite, i->Ain.MovSeg.dst);
> > ++ return;
> > ++ case Ain_MovToSeg64:
> > ++ addHRegUse(u, HRmRead, i->Ain.MovSeg.src);
> > ++ addHRegUse(u, HRmWrite, i->Ain.MovSeg.off);
> > ++ return;
> > ++#endif
> > + default:
> > + ppAMD64Instr(i, mode64);
> > + vpanic("getRegUsage_AMD64Instr");
> > +@@ -1808,6 +1850,16 @@ void mapRegs_AMD64Instr ( HRegRemap* m, AMD64Instr*
> > i, Bool mode64 )
> > + case Ain_ProfInc:
> > + /* hardwires r11 -- nothing to modify. */
> > + return;
> > ++#if defined(__OpenBSD__)
> > ++ case Ain_MovFromSeg64:
> > ++ mapReg(m, &i->Ain.MovSeg.off);
> > ++ mapReg(m, &i->Ain.MovSeg.dst);
> > ++ return;
> > ++ case Ain_MovToSeg64:
> > ++ mapReg(m, &i->Ain.MovSeg.src);
> > ++ mapReg(m, &i->Ain.MovSeg.off);
> > ++ return;
> > ++#endif
> > + default:
> > + ppAMD64Instr(i, mode64);
> > + vpanic("mapRegs_AMD64Instr");
> > +@@ -3522,6 +3574,65 @@ Int emit_AMD64Instr ( /*MB_MOD*/Bool* is_profInc,
> > + goto done;
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++ case Ain_MovFromSeg64: {
> > ++ /* Following rm and reg are means r/m and reg of prefix ModR/M.
> > ++ bit 7 6 5 4 3 2 1 0
> > ++ +---+-----+-----+
> > ++ mod| reg | r/m
> > ++ */
> > ++ UChar rm = 0;
> > ++ UChar d_reg = 0;
> > ++ *p++ = 0x64; /* Prefix of FS register */
> > ++ *p++ = rexAMode_R( i->Ain.MovSeg.dst, i->Ain.MovSeg.off );
> > ++ *p++ = 0x8b; /* Opcode of mov */
> > ++ rm = hregNumber( i->Ain.MovSeg.off );
> > ++ d_reg = hregNumber( i->Ain.MovSeg.dst );
> > ++ switch (rm) {
> > ++ case 4: /* rsp */
> > ++ case 12: /* r12 */
> > ++ *p++ = 0x4 | ((d_reg & 0x7) << 3);
> > ++ *p++ = 0x24;
> > ++ goto done;
> > ++ case 5: /* rbp */
> > ++ case 13: /* r13 */
> > ++ *p++ = 0x45 | ((d_reg & 0x7) << 3);
> > ++ *p++ = 0x00;
> > ++ goto done;
> > ++ }
> > ++ rm = iregBits210( i->Ain.MovSeg.off );
> > ++ d_reg = iregBits210( i->Ain.MovSeg.dst) << 3;
> > ++ *p++ = rm | d_reg;
> > ++ goto done;
> > ++ }
> > ++
> > ++ case Ain_MovToSeg64: {
> > ++ UChar rm = 0;
> > ++ UChar s_reg = 0;
> > ++ UChar o_reg = 0;
> > ++ *p++ = 0x64; /* Prefix of FS register */
> > ++ *p++ = rexAMode_R( i->Ain.MovSeg.src, i->Ain.MovSeg.off );
> > ++ *p++ = 0x89; /* Opcode of mov */
> > ++ rm = hregNumber( i->Ain.MovSeg.off );
> > ++ o_reg = rm & 0x7;
> > ++ s_reg = (hregNumber( i->Ain.MovSeg.src ) & 0x7) << 3;
> > ++ switch (rm) {
> > ++ case 4: /* rsp */
> > ++ case 12: /* r12 */
> > ++ *p++ = s_reg | o_reg;
> > ++ *p++ = 0x24;
> > ++ goto done;
> > ++ case 5: /* rbp */
> > ++ case 13: /* r13 */
> > ++ *p++ = 0x40 | s_reg | o_reg;
> > ++ *p++ = 0x00;
> > ++ goto done;
> > ++ }
> > ++ *p++ = s_reg | o_reg;
> > ++ goto done;
> > ++ }
> > ++#endif
> > ++
> > + default:
> > + goto bad;
> > + }
> > Index: patches/patch-VEX_priv_host_amd64_defs_h
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_host_amd64_defs_h
> > diff -N patches/patch-VEX_priv_host_amd64_defs_h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_host_amd64_defs_h 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,38 @@
> > +--- VEX/priv/host_amd64_defs.h.orig
> > ++++ VEX/priv/host_amd64_defs.h
> > +@@ -403,6 +403,10 @@ typedef
> > + //uu Ain_AvxReRg, /* AVX binary general reg-reg, Re, Rg */
> > + Ain_EvCheck, /* Event check */
> > + Ain_ProfInc /* 64-bit profile counter increment */
> > ++#if defined(__OpenBSD__)
> > ++ ,Ain_MovFromSeg64 /* 64-bit move sreg:(reg),reg */
> > ++ ,Ain_MovToSeg64 /* 64-bit move sreg:(reg),reg */
> > ++#endif
> > + }
> > + AMD64InstrTag;
> > +
> > +@@ -686,6 +690,13 @@ typedef
> > + installed later, post-translation, by patching it in,
> > + as it is not known at translation time. */
> > + } ProfInc;
> > ++#if defined(__OpenBSD__)
> > ++ struct {
> > ++ HReg src;
> > ++ HReg off;
> > ++ HReg dst;
> > ++ } MovSeg;
> > ++#endif
> > +
> > + } Ain;
> > + }
> > +@@ -744,6 +755,10 @@ extern AMD64Instr* AMD64Instr_SseShuf ( Int order,
> > HReg src, HReg dst );
> > + extern AMD64Instr* AMD64Instr_EvCheck ( AMD64AMode* amCounter,
> > + AMD64AMode* amFailAddr );
> > + extern AMD64Instr* AMD64Instr_ProfInc ( void );
> > ++#if defined(__OpenBSD__)
> > ++extern AMD64Instr* AMD64Instr_MovFromSeg64 ( HReg, HReg );
> > ++extern AMD64Instr* AMD64Instr_MovToSeg64 ( HReg, HReg );
> > ++#endif
> > +
> > +
> > + extern void ppAMD64Instr ( AMD64Instr*, Bool );
> > Index: patches/patch-VEX_priv_host_amd64_isel_c
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_host_amd64_isel_c
> > diff -N patches/patch-VEX_priv_host_amd64_isel_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_host_amd64_isel_c 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,25 @@
> > +--- VEX/priv/host_amd64_isel.c.orig
> > ++++ VEX/priv/host_amd64_isel.c
> > +@@ -1369,6 +1369,22 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env,
> > IRExpr* e )
> > + return dst;
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++ if (e->Iex.Binop.op == Iop_MovFromSeg64) {
> > ++ HReg dst = iselIntExpr_R(env, e->Iex.Binop.arg1);
> > ++ HReg off = iselIntExpr_R(env, e->Iex.Binop.arg2);
> > ++ addInstr(env, AMD64Instr_MovFromSeg64(off, dst));
> > ++ return dst;
> > ++ }
> > ++
> > ++ if (e->Iex.Binop.op == Iop_MovToSeg64) {
> > ++ HReg src = iselIntExpr_R(env, e->Iex.Binop.arg1);
> > ++ HReg off = iselIntExpr_R(env, e->Iex.Binop.arg2);
> > ++ addInstr(env, AMD64Instr_MovToSeg64(src, off));
> > ++ return src;
> > ++ }
> > ++#endif
> > ++
> > + break;
> > + }
> > +
> > Index: patches/patch-VEX_priv_ir_defs_c
> > ===================================================================
> > RCS file: patches/patch-VEX_priv_ir_defs_c
> > diff -N patches/patch-VEX_priv_ir_defs_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_priv_ir_defs_c 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,39 @@
> > +--- VEX/priv/ir_defs.c.orig
> > ++++ VEX/priv/ir_defs.c
> > +@@ -1235,6 +1235,13 @@ void ppIROp ( IROp op )
> > +
> > + case Iop_PwBitMtxXpose64x2: vex_printf("BitMatrixTranspose64x2");
> > return;
> > +
> > ++#if defined(__OpenBSD__)
> > ++ case Iop_MovFromSeg8 ... Iop_MovFromSeg64:
> > ++ str = "MovFromSeg"; base = Iop_MovFromSeg8; break;
> > ++ case Iop_MovToSeg8 ... Iop_MovToSeg64:
> > ++ str = "MovToSeg"; base = Iop_MovToSeg8; break;
> > ++#endif
> > ++
> > + default: vpanic("ppIROp(1)");
> > + }
> > +
> > +@@ -2480,7 +2487,9 @@ void typeOfPrimop ( IROp op,
> > + switch (op) {
> > + case Iop_Add8: case Iop_Sub8: case Iop_Mul8:
> > + case Iop_Or8: case Iop_And8: case Iop_Xor8:
> > ++#if defined(__OpenBSD__)
> > + BINARY(Ity_I8,Ity_I8, Ity_I8);
> > ++#endif
> > +
> > + case Iop_Add16: case Iop_Sub16: case Iop_Mul16:
> > + case Iop_Or16: case Iop_And16: case Iop_Xor16:
> > +@@ -3391,6 +3400,12 @@ void typeOfPrimop ( IROp op,
> > + case Iop_SarN16x16: case Iop_SarN32x8:
> > + BINARY(Ity_V256,Ity_I8, Ity_V256);
> > +
> > ++#if defined(__OpenBSD__)
> > ++ case Iop_MovFromSeg64:
> > ++ case Iop_MovToSeg64:
> > ++ BINARY( Ity_I64, Ity_I64, Ity_I64 );
> > ++#endif
> > ++
> > + default:
> > + ppIROp(op);
> > + vpanic("typeOfPrimop");
> > Index: patches/patch-VEX_pub_libvex_ir_h
> > ===================================================================
> > RCS file: patches/patch-VEX_pub_libvex_ir_h
> > diff -N patches/patch-VEX_pub_libvex_ir_h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-VEX_pub_libvex_ir_h 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,14 @@
> > +--- VEX/pub/libvex_ir.h.orig
> > ++++ VEX/pub/libvex_ir.h
> > +@@ -1815,6 +1815,11 @@ typedef
> > + Iop_RSqrtEst32Fx8,
> > + Iop_RecipEst32Fx8,
> > +
> > ++#if defined(__OpenBSD__)
> > ++ Iop_MovFromSeg8, Iop_MovFromSeg16, Iop_MovFromSeg32,
> > Iop_MovFromSeg64,
> > ++ Iop_MovToSeg8, Iop_MovToSeg16, Iop_MovToSeg32, Iop_MovToSeg64,
> > ++#endif
> > ++
> > + Iop_Max32Fx8, Iop_Min32Fx8,
> > + Iop_Max64Fx4, Iop_Min64Fx4,
> > + Iop_LAST /* must be the last enumerator */
> > Index: patches/patch-coregrind_link_tool_exe_openbsd_in
> > ===================================================================
> > RCS file: patches/patch-coregrind_link_tool_exe_openbsd_in
> > diff -N patches/patch-coregrind_link_tool_exe_openbsd_in
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_link_tool_exe_openbsd_in 27 Sep 2019
> > 03:08:46 -0000
> > @@ -0,0 +1,16 @@
> > +--- coregrind/link_tool_exe_openbsd.in.orig Fri Sep 27 10:40:06 2019
> > ++++ coregrind/link_tool_exe_openbsd.in Fri Sep 27 10:45:59 2019
> > +@@ -77,7 +77,12 @@
> > + my $origbase = 0x400000;
> > + system(sprintf "sed -e 's|%x|%x|g' < $ldscript > $temp", $origbase,
> > $notebase);
> > +
> > +-my $cmd = sprintf "$cc -static -nopie -Wl,-Ttext=0x%x -Wl,-T,$temp",
> > $textbase;
> > ++my $cmd = sprintf "$cc -static -nopie -Wl,-zwxneeded -Wl,-Ttext=0x%x
> > -Wl,-T,$temp", $textbase;
> > ++# XXX The '-s' option was not specified when executing the install
> > command.
> > ++# Instead '--strip-all' is now executed at link time.
> > ++# strip command rewrite offset and align in ELF file. Therefor, when
> > valgrind
> > ++# launch memcheck-amd64-openbsd, an Abort trap occurs in the execvp()
> > system
> > ++# call.
> > +
> > + # Add the rest of the parameters
> > + foreach my $n (2 .. $#ARGV) {
> > Index: patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> > diff -N patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_aspacemgr_aspacemgr-common_c 27 Sep 2019
> > 03:08:46 -0000
> > @@ -0,0 +1,14 @@
> > +--- coregrind/m_aspacemgr/aspacemgr-common.c.orig
> > ++++ coregrind/m_aspacemgr/aspacemgr-common.c
> > +@@ -458,7 +458,11 @@ VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr*
> > initial_sp )
> > + szB = VG_STACK_GUARD_SZB
> > + + VG_STACK_ACTIVE_SZB + VG_STACK_GUARD_SZB;
> > +
> > ++#if defined(__OpenBSD__)
> > ++ sres = VG_(am_mmap_anon_float_valgrind_stack)( szB );
> > ++#else
> > + sres = VG_(am_mmap_anon_float_valgrind)( szB );
> > ++#endif
> > + if (sr_isError(sres))
> > + return NULL;
> > +
> > Index: patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> > diff -N patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_aspacemgr_aspacemgr-linux_c 27 Sep 2019
> > 03:08:46 -0000
> > @@ -0,0 +1,57 @@
> > +--- coregrind/m_aspacemgr/aspacemgr-linux.c.orig
> > ++++ coregrind/m_aspacemgr/aspacemgr-linux.c
> > +@@ -2543,6 +2543,54 @@ SysRes VG_(am_mmap_anon_float_valgrind)( SizeT
> > length )
> > + return sres;
> > + }
> > +
> > ++#if defined(__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_PROT_EXEC,
> > ++ 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). */
> > +
> > + void* VG_(am_shadow_alloc)(SizeT size)
> > Index: patches/patch-coregrind_m_debuglog_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_debuglog_c
> > diff -N patches/patch-coregrind_m_debuglog_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_debuglog_c 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,14 @@
> > +--- coregrind/m_debuglog.c.orig
> > ++++ coregrind/m_debuglog.c
> > +@@ -470,7 +470,11 @@ static UInt local_sys_write_stderr ( HChar* buf, Int
> > n )
> > + __asm__ volatile (
> > + "subq $256, %%rsp\n" /* don't trash the stack redzone */
> > + "pushq %%r15\n" /* r15 is callee-save */
> > ++#if __clang_major__ >= 6
> > ++ "lea %0, %%r15\n" /* r15 = &block */
> > ++#else
> > + "movq %0, %%r15\n" /* r15 = &block */
> > ++#endif
> > + "pushq %%r15\n" /* save &block */
> > + "movq $"VG_STRINGIFY(__NR_write)", %%rax\n" /* rax = __NR_write */
> > + "movq $2, %%rdi\n" /* rdi = stderr */
> > Index: patches/patch-coregrind_m_libcproc_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_libcproc_c
> > diff -N patches/patch-coregrind_m_libcproc_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_libcproc_c 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,16 @@
> > +--- coregrind/m_libcproc.c.orig
> > ++++ coregrind/m_libcproc.c
> > +@@ -1033,6 +1033,13 @@ void VG_(flush_dcache) ( void *ptr, SizeT nbytes )
> > + # endif
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++void VG_(__set_tcb)(void *tcb)
> > ++{
> > ++ (void)VG_(do_syscall1)(__NR___set_tcb, tcb);
> > ++}
> > ++#endif
> > ++
> > + /*--------------------------------------------------------------------*/
> > + /*--- end ---*/
> > + /*--------------------------------------------------------------------*/
> > Index: patches/patch-coregrind_m_main_c
> > ===================================================================
> > RCS file: /cvs/ports/devel/valgrind/patches/patch-coregrind_m_main_c,v
> > retrieving revision 1.2
> > diff -u -p -r1.2 patch-coregrind_m_main_c
> > --- patches/patch-coregrind_m_main_c 4 Feb 2019 23:34:10 -0000
> > 1.2
> > +++ patches/patch-coregrind_m_main_c 27 Sep 2019 03:08:46 -0000
> > @@ -6,16 +6,101 @@ https://bitbucket.org/uebayasi/valgrind-
> > Index: coregrind/m_main.c
> > --- coregrind/m_main.c.orig
> > +++ coregrind/m_main.c
> > -@@ -1725,7 +1725,9 @@ Int valgrind_main ( Int argc, HChar **argv, HChar
> > **en
> > +@@ -1524,7 +1524,38 @@
> > +
> > + /* --- end of Forwards decls to do with shutdown --- */
> > +
> > ++#if defined(__OpenBSD__)
> > ++#include <tib.h>
> > +
> > ++#define ELF_ROUND(x,malign) (((x) + (malign)-1) & ~((malign)-1))
> > ++
> > ++extern void setup_static_tib(void);
> > ++
> > ++void
> > ++setup_static_tib(void)
> > ++{
> > ++ struct tib *tib;
> > ++ char *base;
> > ++ SysRes sres;
> > ++ SizeT size;
> > ++
> > ++ size = ELF_ROUND(0 + sizeof *tib, 4096);
> > ++ sres = VG_(am_mmap_anon_float_valgrind)(size);
> > ++ if (sr_isError(sres)) {
> > ++ VG_(out_of_memory_NORETURN)("TIB", size);
> > ++ /*NOTREACHED*/
> > ++ }
> > ++ base = (char *)(AddrH)sr_Res(sres);
> > ++
> > ++ tib = (struct tib *)base;
> > ++
> > ++ TIB_INIT(tib, NULL, NULL);
> > ++ tib->tib_tid = VG_(gettid)();
> > ++
> > ++ VG_(__set_tcb)(TIB_TO_TCB(tib));
> > ++}
> > ++#endif
> > ++
> > + /* By the time we get to valgrind_main, the_iicii should already have
> > + been filled in with any important details as required by whatever
> > + OS we have been built for.
> > +@@ -1612,6 +1643,7 @@
> > + // Ensure we're on a plausible stack.
> > + // p: logging
> > + //--------------------------------------------------------------
> > ++#if !defined(__OpenBSD__)
> > + VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
> > + { HChar* limLo = (HChar*)(&VG_(interim_stack).bytes[0]);
> > + HChar* limHi = limLo + sizeof(VG_(interim_stack));
> > +@@ -1643,6 +1675,7 @@
> > + VG_(exit)(1);
> > + }
> > + }
> > ++#endif
> > +
> > + //--------------------------------------------------------------
> > + // Ensure we have a plausible pointer to the stack on which
> > +@@ -1725,7 +1758,9 @@
> > // child processes will have a reasonable brk value.
> > VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
> > zero.rlim_max = VG_(client_rlimit_data).rlim_max;
> > -+#if 0
> > ++#if !defined(__OpenBSD__)
> > VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
> > +#endif
> >
> > // Get the current process stack rlimit.
> > VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
> > +@@ -2433,6 +2468,10 @@
> > + VG_(address_of_m_main_shutdown_actions_NORETURN)
> > + = & shutdown_actions_NORETURN;
> > +
> > ++#if defined(__OpenBSD__)
> > ++ setup_static_tib();
> > ++#endif
> > ++
> > + /* Run the first thread, eventually ending up at the continuation
> > + address. */
> > + VG_(main_thread_wrapper_NORETURN)(1);
> > +@@ -3159,6 +3198,8 @@
> > + "__start:\n"
> > + /* pass args (long argc, char **argv, ...) on stack */
> > + "\tmovq %rsp, %rdi\n"
> > ++#if !defined(__OpenBSD__)
> > ++ /* OpenBSD 6.4 and later can not use BBS for stack area */
> > + /* set up the new stack in %rsi */
> > + "\tmovq $vgPlain_interim_stack, %rsi\n"
> > + "\taddq $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rsi\n"
> > +@@ -3166,6 +3207,9 @@
> > + "\tandq $~15, %rsi\n"
> > + /* install it, and collect the original one */
> > + "\txchgq %rsi, %rsp\n"
> > ++#else
> > ++ "\tmov %rsp, %rsi\n"
> > ++#endif
> > + /* call _start_in_C_amd64_freebsd, passing it the startup %rsp */
> > + "\tcall _start_in_C_amd64_openbsd\n"
> > + "\thlt\n"
> > @@ -3233,7 +3235,7 @@ __asm(" .section \".note.openbsd.ident\", \"a\"\n"
> > #if !defined(VGO_openbsd)
> > #include <elf.h>
> > Index: patches/patch-coregrind_m_scheduler_scheduler_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_scheduler_scheduler_c
> > diff -N patches/patch-coregrind_m_scheduler_scheduler_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_scheduler_scheduler_c 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,74 @@
> > +--- coregrind/m_scheduler/scheduler.c.orig
> > ++++ coregrind/m_scheduler/scheduler.c
> > +@@ -854,6 +854,9 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> > + volatile ThreadState* tst = NULL; /* stop gcc complaining */
> > + volatile Int done_this_time = 0;
> > + volatile HWord host_code_addr = 0;
> > ++#if defined(__OpenBSD__)
> > ++ volatile UInt host_code_len = 0;
> > ++#endif
> > +
> > + /* Paranoia */
> > + vg_assert(VG_(is_valid_tid)(tid));
> > +@@ -879,8 +882,15 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> > + } else {
> > + /* normal case -- redir translation */
> > + UInt cno = (UInt)VG_TT_FAST_HASH((Addr)tst->arch.vex.VG_INSTR_PTR);
> > ++#if defined(__OpenBSD__)
> > ++ if (LIKELY(VG_(tt_fast)[cno].guest ==
> > (Addr)tst->arch.vex.VG_INSTR_PTR)) {
> > ++ host_code_addr = VG_(tt_fast)[cno].host;
> > ++ host_code_len = VG_(tt_fast)[cno].len;
> > ++ }
> > ++#else
> > + if (LIKELY(VG_(tt_fast)[cno].guest ==
> > (Addr)tst->arch.vex.VG_INSTR_PTR))
> > + host_code_addr = VG_(tt_fast)[cno].host;
> > ++#endif
> > + else {
> > + AddrH res = 0;
> > + /* not found in VG_(tt_fast). Searching here the transtab
> > +@@ -932,6 +942,22 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> > + vg_assert(VG_(in_generated_code) == False);
> > + VG_(in_generated_code) = True;
> > +
> > ++#if defined(__OpenBSD__)
> > ++ if (host_code_len > 0) {
> > ++ SysRes sres;
> > ++
> > ++ /* Protect the guard areas. */
> > ++ sres = VG_(am_do_mprotect_NO_NOTIFY)(
> > ++ host_code_addr, host_code_len,
> > ++ VKI_PROT_READ | VKI_PROT_EXEC
> > ++ );
> > ++ if (sr_isError(sres)) {
> > ++ VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
> > ++ vg_assert(0);
> > ++ }
> > ++ }
> > ++#endif
> > ++
> > + SCHEDSETJMP(
> > + tid,
> > + jumped,
> > +@@ -942,6 +968,22 @@ void run_thread_for_a_while ( /*OUT*/HWord* two_words,
> > + )
> > + );
> > +
> > ++#if defined(__OpenBSD__)
> > ++ if (host_code_len > 0) {
> > ++ SysRes sres;
> > ++
> > ++ /* Protect the guard areas. */
> > ++ sres = VG_(am_do_mprotect_NO_NOTIFY)(
> > ++ host_code_addr, host_code_len,
> > ++ VKI_PROT_READ | VKI_PROT_WRITE | VKI_PROT_EXEC
> > ++ );
> > ++ if (sr_isError(sres)) {
> > ++ VG_(printf)("valgrind: m_ume.c: mprotect failed\n");
> > ++ vg_assert(0);
> > ++ }
> > ++ }
> > ++#endif
> > ++
> > + vg_assert(VG_(in_generated_code) == True);
> > + VG_(in_generated_code) = False;
> > +
> > Index: patches/patch-coregrind_m_transtab_c
> > ===================================================================
> > RCS file: patches/patch-coregrind_m_transtab_c
> > diff -N patches/patch-coregrind_m_transtab_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_m_transtab_c 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,60 @@
> > +--- coregrind/m_transtab.c.orig Wed Nov 26 04:41:21 2014
> > ++++ coregrind/m_transtab.c Mon Dec 10 17:05:02 2018
> > +@@ -1322,11 +1321,18 @@
> > + return k32 % N_TTES_PER_SECTOR;
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++static void setFastCacheEntry ( Addr64 key, ULong* tcptr, UInt len )
> > ++#else
> > + static void setFastCacheEntry ( Addr64 key, ULong* tcptr )
> > ++#endif
> > + {
> > + UInt cno = (UInt)VG_TT_FAST_HASH(key);
> > + VG_(tt_fast)[cno].guest = (Addr)key;
> > + VG_(tt_fast)[cno].host = (Addr)tcptr;
> > ++#if defined(__OpenBSD__)
> > ++ VG_(tt_fast)[cno].len = (Addr)len;
> > ++#endif
> > + n_fast_updates++;
> > + /* This shouldn't fail. It should be assured by m_translate
> > + which should reject any attempt to make translation of code
> > +@@ -1670,7 +1676,11 @@
> > + }
> > +
> > + /* Update the fast-cache. */
> > ++#if defined(__OpenBSD__)
> > ++ setFastCacheEntry( entry, tcptr, code_len );
> > ++#else
> > + setFastCacheEntry( entry, tcptr );
> > ++#endif
> > +
> > + /* Note the eclass numbers for this translation. */
> > + upd_eclasses_after_add( §ors[y], i );
> > +@@ -1712,8 +1722,13 @@
> > + && sectors[sno].tt[k].entry == guest_addr) {
> > + /* found it */
> > + if (upd_cache)
> > ++#if defined(__OpenBSD__)
> > ++ setFastCacheEntry(
> > ++ guest_addr, sectors[sno].tt[k].tcptr, 0 );
> > ++#else
> > + setFastCacheEntry(
> > + guest_addr, sectors[sno].tt[k].tcptr );
> > ++#endif
> > + if (res_hcode)
> > + *res_hcode = (AddrH)sectors[sno].tt[k].tcptr;
> > + if (res_sNo)
> > +@@ -2204,7 +2219,12 @@
> > + vg_assert(sizeof(Addr64) == 8);
> > + /* check fast cache entries really are 2 words long */
> > + vg_assert(sizeof(Addr) == sizeof(void*));
> > ++#if defined(__OpenBSD__)
> > ++ vg_assert(sizeof(FastCacheEntry) ==
> > ++ (2 * sizeof(Addr) + (2 * sizeof (UInt))));
> > ++#else
> > + vg_assert(sizeof(FastCacheEntry) == 2 * sizeof(Addr));
> > ++#endif
> > + /* check fast cache entries are packed back-to-back with no spaces */
> > + vg_assert(sizeof( VG_(tt_fast) ) == VG_TT_FAST_SIZE *
> > sizeof(FastCacheEntry));
> > + /* check fast cache is aligned as we requested. Not fatal if it
> > Index: patches/patch-coregrind_pub_core_aspacemgr_h
> > ===================================================================
> > RCS file: patches/patch-coregrind_pub_core_aspacemgr_h
> > diff -N patches/patch-coregrind_pub_core_aspacemgr_h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_pub_core_aspacemgr_h 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,13 @@
> > +--- coregrind/pub_core_aspacemgr.h.orig
> > ++++ coregrind/pub_core_aspacemgr.h
> > +@@ -242,6 +242,9 @@ extern SysRes VG_(am_mmap_anon_float_client) ( SizeT
> > length,
> > + Int prot );
> > + segment array accordingly. This is fundamentally how V allocates
> > + itself more address space when needed. */
> > + extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
> > ++#if defined(__OpenBSD__)
> > ++extern SysRes VG_(am_mmap_anon_float_valgrind_stack)( SizeT cszB );
> > ++#endif
> > +
> > + /* Map privately a file at an unconstrained address for V, and update the
> > + segment array accordingly. This is used by V for transiently
> > Index: patches/patch-coregrind_pub_core_transtab_h
> > ===================================================================
> > RCS file: patches/patch-coregrind_pub_core_transtab_h
> > diff -N patches/patch-coregrind_pub_core_transtab_h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-coregrind_pub_core_transtab_h 27 Sep 2019 03:08:46
> > -0000
> > @@ -0,0 +1,12 @@
> > +--- coregrind/pub_core_transtab.h.orig
> > ++++ coregrind/pub_core_transtab.h
> > +@@ -45,6 +45,9 @@ typedef
> > + struct {
> > + Addr guest;
> > + Addr host;
> > ++#if defined(__OpenBSD__)
> > ++ UInt len;
> > ++#endif
> > + }
> > + FastCacheEntry;
> > +
> > Index: patches/patch-include_vki_vki-openbsd_h
> > ===================================================================
> > RCS file: patches/patch-include_vki_vki-openbsd_h
> > diff -N patches/patch-include_vki_vki-openbsd_h
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-include_vki_vki-openbsd_h 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,13 @@
> > +--- include/vki/vki-openbsd.h.orig
> > ++++ include/vki/vki-openbsd.h
> > +@@ -1544,9 +1544,9 @@
> > + #define VKI_MAP_PRIVATE 0x02 /* Changes are private */
> > + #define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */
> > + #define VKI_MAP_NORESERVE 0x0040 /* don't check for reservations
> > */
> > +-#define VKI_MAP_STACK 0x400
> > + #define VKI_MAP_ANON 0x1000 /* don't use a file */
> > + #define VKI_MAP_ANONYMOUS VKI_MAP_ANON
> > ++#define VKI_MAP_STACK 0x4000
> > +
> > + //----------------------------------------------------------------------
> > + // From sys/stat.h
> > Index: patches/patch-memcheck_mc_translate_c
> > ===================================================================
> > RCS file: patches/patch-memcheck_mc_translate_c
> > diff -N patches/patch-memcheck_mc_translate_c
> > --- /dev/null 1 Jan 1970 00:00:00 -0000
> > +++ patches/patch-memcheck_mc_translate_c 27 Sep 2019 03:08:46 -0000
> > @@ -0,0 +1,15 @@
> > +--- memcheck/mc_translate.c.orig
> > ++++ memcheck/mc_translate.c
> > +@@ -4222,6 +4222,12 @@ IRAtom* expr2vbits_Binop ( MCEnv* mce,
> > + binop(Iop_V128HLtoV256, qV, shV));
> > + }
> > +
> > ++#if defined(__OpenBSD__)
> > ++ case Iop_MovFromSeg64:
> > ++ case Iop_MovToSeg64:
> > ++ return assignNew('V', mce, Ity_I64, binop(op, atom1, atom2));
> > ++#endif
> > ++
> > + default:
> > + ppIROp(op);
> > + VG_(tool_panic)("memcheck:expr2vbits_Binop");
> > --
> > ASOU Masato
>