<commit_before>/* **********************************************************
 * Copyright (c) 2010-2012 Google, Inc.  All rights reserved.
 * Copyright (c) 2000-2010 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Copyright (c) 2003-2007 Determina Corp. */
/* Copyright (c) 2001-2003 Massachusetts Institute of Technology */
/* Copyright (c) 2000-2001 Hewlett-Packard Company */

/* file "arch.h" -- internal x86-specific definitions
 *
 * References: 
 *   "Intel Architecture Software Developer's Manual", 1999.
 */

#ifndef X86_ARCH_H
#define X86_ARCH_H

#include <stddef.h> /* for offsetof */
#include "instr.h" /* for reg_id_t */

/* FIXME: check on all platforms: these are for Fedora 8 and XP SP2
 * Keep in synch w/ defines in pre_inject_asm.asm
 */
#define CS32_SELECTOR 0x23
#define CS64_SELECTOR 0x33

/* dcontext_t field offsets 
 * N.B.: DO NOT USE offsetof(dcontext_t) anywhere else if passing to the
 * dcontext operand construction routines!
 * Otherwise we will have issues w/ the upcontext offset game below
 */

/* offs is not raw offset, but includes upcontext size, so we
 * can tell unprotected from normal!
 * unprotected are raw 0..sizeof(unprotected_context_t)
 * protected are raw + sizeof(unprotected_context_t)
 * (see the instr.c routines for dcontext instr building)
 * FIXME: we could get rid of this hack if unprotected_context_t == priv_mcontext_t
 */
#define PROT_OFFS         (sizeof(unprotected_context_t))
#define MC_OFFS           (offsetof(unprotected_context_t, mcontext))

#define XAX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xax)))
#define XBX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xbx)))
#define XCX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xcx)))
#define XDX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xdx)))
#define XSI_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xsi)))
#define XDI_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xdi)))
#define XBP_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xbp)))
#define XSP_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xsp)))
#define XFLAGS_OFFSET     ((MC_OFFS) + (offsetof(priv_mcontext_t, xflags)))
#define PC_OFFSET         ((MC_OFFS) + (offsetof(priv_mcontext_t, pc)))
#ifdef X64
# define R8_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, r8)))
# define R9_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, r9)))
# define R10_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r10)))
# define R11_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r11)))
# define R12_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r12)))
# define R13_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r13)))
# define R14_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r14)))
# define R15_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r15)))
#endif
#define XMM_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, ymm)))

#define ERRNO_OFFSET      (offsetof(unprotected_context_t, errno))
#define AT_SYSCALL_OFFSET (offsetof(unprotected_context_t, at_syscall))

#define NEXT_TAG_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, next_tag))
#define LAST_EXIT_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, last_exit))
#define DSTACK_OFFSET          ((PROT_OFFS)+offsetof(dcontext_t, dstack))
#define NATIVE_EXEC_RETVAL_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, native_exec_retval))
#define NATIVE_EXEC_RETLOC_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, native_exec_retloc))
#ifdef RETURN_STACK
# define RSTACK_OFFSET         ((PROT_OFFS)+offsetof(dcontext_t, rstack))
# define TOP_OF_RSTACK_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, top_of_rstack))
#endif

#define FRAGMENT_FIELD_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, fragment_field))
#define PRIVATE_CODE_OFFSET    ((PROT_OFFS)+offsetof(dcontext_t, private_code))

#ifdef WINDOWS
# ifdef CLIENT_INTERFACE
#  define APP_ERRNO_OFFSET      ((PROT_OFFS)+offsetof(dcontext_t, app_errno))
#  define APP_FLS_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, app_fls_data))
#  define PRIV_FLS_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, priv_fls_data))
#  define APP_RPC_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, app_nt_rpc))
#  define PRIV_RPC_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, priv_nt_rpc))
# endif
# define NONSWAPPED_SCRATCH_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, nonswapped_scratch))
#endif

#ifdef TRACE_HEAD_CACHE_INCR 
# define TRACE_HEAD_PC_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, trace_head_pc))
#endif

#ifdef NATIVE_RETURN_CALLDEPTH
# define CALL_DEPTH_OFFSET     ((PROT_OFFS)+offsetof(dcontext_t, call_depth))
#endif

#ifdef WINDOWS
# define SYSENTER_STORAGE_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, sysenter_storage))
# define IGNORE_ENTEREXIT_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, ignore_enterexit))
#endif

#ifdef CLIENT_INTERFACE
# define CLIENT_DATA_OFFSET    ((PROT_OFFS)+offsetof(dcontext_t, client_data))
#endif

#define COARSE_IB_SRC_OFFSET   ((PROT_OFFS)+offsetof(dcontext_t, coarse_exit.src_tag))
#define COARSE_DIR_EXIT_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, coarse_exit.dir_exit))

int
reg_spill_tls_offs(reg_id_t reg);

#define OPSZ_SAVED_XMM (YMM_ENABLED() ? OPSZ_32 : OPSZ_16)
#define REG_SAVED_XMM0 (YMM_ENABLED() ? REG_YMM0 : REG_XMM0)

/* Xref the partially overlapping CONTEXT_PRESERVE_XMM */
/* This routine also determines whether ymm registers should be saved */
static inline bool
preserve_xmm_caller_saved(void)
{
    /* PR 264138: we must preserve xmm0-5 if on a 64-bit Windows kernel.
     * PR 302107: we must preserve xmm0-15 for 64-bit Linux apps.
     * PR 306394: for now we do not preserve xmm0-7, which are technically
     * caller-saved, for 32-bit Windows.
     */
    return IF_X64_ELSE(true,
                       /* i#139: we save xmm0-7 in 32-bit Linux. */
                       IF_WINDOWS_ELSE(is_wow64_process(NT_CURRENT_PROCESS), true)) &&
        proc_has_feature(FEATURE_SSE) /* do xmm registers exist? */;
}

typedef enum {
    IBL_UNLINKED,
    IBL_DELETE,
#ifdef X64
    /* PR 257963: trace inline cmp has separate entries b/c it saves flags */
    IBL_TRACE_CMP,
    IBL_TRACE_CMP_UNLINKED,
#endif
    IBL_LINKED,
    
    IBL_TEMPLATE, /* a template is presumed to be always linked */
    IBL_LINK_STATE_END
} ibl_entry_point_type_t;

/* we should allow for all {{bb,trace} x {ret,ind call, ind jmp} x {shared, private}} */
/* combinations of routines which are in turn  x {unlinked, linked} */
typedef enum {
    /* FIXME: have a separate flag for private vs shared */
    IBL_BB_SHARED, 
    IBL_SOURCE_TYPE_START = IBL_BB_SHARED,
    IBL_TRACE_SHARED,
    IBL_BB_PRIVATE,
    IBL_TRACE_PRIVATE,
    IBL_COARSE_SHARED, /* no coarse private, for now */
    IBL_SOURCE_TYPE_END
} ibl_source_fragment_type_t;

#define DEFAULT_IBL_BB() \<commit_msg>fixes issue 139 + preserve xmm regs on 32-bit windows kernel<commit_after>/* **********************************************************
 * Copyright (c) 2010-2012 Google, Inc.  All rights reserved.
 * Copyright (c) 2000-2010 VMware, Inc.  All rights reserved.
 * **********************************************************/

/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * 
 * * Neither the name of VMware, Inc. nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without
 *   specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Copyright (c) 2003-2007 Determina Corp. */
/* Copyright (c) 2001-2003 Massachusetts Institute of Technology */
/* Copyright (c) 2000-2001 Hewlett-Packard Company */

/* file "arch.h" -- internal x86-specific definitions
 *
 * References: 
 *   "Intel Architecture Software Developer's Manual", 1999.
 */

#ifndef X86_ARCH_H
#define X86_ARCH_H

#include <stddef.h> /* for offsetof */
#include "instr.h" /* for reg_id_t */

/* FIXME: check on all platforms: these are for Fedora 8 and XP SP2
 * Keep in synch w/ defines in pre_inject_asm.asm
 */
#define CS32_SELECTOR 0x23
#define CS64_SELECTOR 0x33

/* dcontext_t field offsets 
 * N.B.: DO NOT USE offsetof(dcontext_t) anywhere else if passing to the
 * dcontext operand construction routines!
 * Otherwise we will have issues w/ the upcontext offset game below
 */

/* offs is not raw offset, but includes upcontext size, so we
 * can tell unprotected from normal!
 * unprotected are raw 0..sizeof(unprotected_context_t)
 * protected are raw + sizeof(unprotected_context_t)
 * (see the instr.c routines for dcontext instr building)
 * FIXME: we could get rid of this hack if unprotected_context_t == priv_mcontext_t
 */
#define PROT_OFFS         (sizeof(unprotected_context_t))
#define MC_OFFS           (offsetof(unprotected_context_t, mcontext))

#define XAX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xax)))
#define XBX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xbx)))
#define XCX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xcx)))
#define XDX_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xdx)))
#define XSI_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xsi)))
#define XDI_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xdi)))
#define XBP_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xbp)))
#define XSP_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, xsp)))
#define XFLAGS_OFFSET     ((MC_OFFS) + (offsetof(priv_mcontext_t, xflags)))
#define PC_OFFSET         ((MC_OFFS) + (offsetof(priv_mcontext_t, pc)))
#ifdef X64
# define R8_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, r8)))
# define R9_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, r9)))
# define R10_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r10)))
# define R11_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r11)))
# define R12_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r12)))
# define R13_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r13)))
# define R14_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r14)))
# define R15_OFFSET       ((MC_OFFS) + (offsetof(priv_mcontext_t, r15)))
#endif
#define XMM_OFFSET        ((MC_OFFS) + (offsetof(priv_mcontext_t, ymm)))

#define ERRNO_OFFSET      (offsetof(unprotected_context_t, errno))
#define AT_SYSCALL_OFFSET (offsetof(unprotected_context_t, at_syscall))

#define NEXT_TAG_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, next_tag))
#define LAST_EXIT_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, last_exit))
#define DSTACK_OFFSET          ((PROT_OFFS)+offsetof(dcontext_t, dstack))
#define NATIVE_EXEC_RETVAL_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, native_exec_retval))
#define NATIVE_EXEC_RETLOC_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, native_exec_retloc))
#ifdef RETURN_STACK
# define RSTACK_OFFSET         ((PROT_OFFS)+offsetof(dcontext_t, rstack))
# define TOP_OF_RSTACK_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, top_of_rstack))
#endif

#define FRAGMENT_FIELD_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, fragment_field))
#define PRIVATE_CODE_OFFSET    ((PROT_OFFS)+offsetof(dcontext_t, private_code))

#ifdef WINDOWS
# ifdef CLIENT_INTERFACE
#  define APP_ERRNO_OFFSET      ((PROT_OFFS)+offsetof(dcontext_t, app_errno))
#  define APP_FLS_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, app_fls_data))
#  define PRIV_FLS_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, priv_fls_data))
#  define APP_RPC_OFFSET        ((PROT_OFFS)+offsetof(dcontext_t, app_nt_rpc))
#  define PRIV_RPC_OFFSET       ((PROT_OFFS)+offsetof(dcontext_t, priv_nt_rpc))
# endif
# define NONSWAPPED_SCRATCH_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, nonswapped_scratch))
#endif

#ifdef TRACE_HEAD_CACHE_INCR 
# define TRACE_HEAD_PC_OFFSET  ((PROT_OFFS)+offsetof(dcontext_t, trace_head_pc))
#endif

#ifdef NATIVE_RETURN_CALLDEPTH
# define CALL_DEPTH_OFFSET     ((PROT_OFFS)+offsetof(dcontext_t, call_depth))
#endif

#ifdef WINDOWS
# define SYSENTER_STORAGE_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, sysenter_storage))
# define IGNORE_ENTEREXIT_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, ignore_enterexit))
#endif

#ifdef CLIENT_INTERFACE
# define CLIENT_DATA_OFFSET    ((PROT_OFFS)+offsetof(dcontext_t, client_data))
#endif

#define COARSE_IB_SRC_OFFSET   ((PROT_OFFS)+offsetof(dcontext_t, coarse_exit.src_tag))
#define COARSE_DIR_EXIT_OFFSET ((PROT_OFFS)+offsetof(dcontext_t, coarse_exit.dir_exit))

int
reg_spill_tls_offs(reg_id_t reg);

#define OPSZ_SAVED_XMM (YMM_ENABLED() ? OPSZ_32 : OPSZ_16)
#define REG_SAVED_XMM0 (YMM_ENABLED() ? REG_YMM0 : REG_XMM0)

/* Xref the partially overlapping CONTEXT_PRESERVE_XMM */
/* This routine also determines whether ymm registers should be saved */
static inline bool
preserve_xmm_caller_saved(void)
{
    /* PR 264138: we must preserve xmm0-5 if on a 64-bit Windows kernel.
     * PR 302107: we must preserve xmm0-15 for 64-bit Linux apps.
     * i#139: we save xmm0-7 in 32-bit Linux and Windows b/c DR and client
     * code on modern compilers ends up using xmm regs w/o any flags to easily
     * disable w/o giving up perf.  (Xref PR 306394 where we originally did
     * not preserve xmm0-7 on a 32-bit kernel b/c DR didn't contain any xmm
     * reg usage).
     */
    return proc_has_feature(FEATURE_SSE) /* do xmm registers exist? */;
}

typedef enum {
    IBL_UNLINKED,
    IBL_DELETE,
#ifdef X64
    /* PR 257963: trace inline cmp has separate entries b/c it saves flags */
    IBL_TRACE_CMP,
    IBL_TRACE_CMP_UNLINKED,
#endif
    IBL_LINKED,
    
    IBL_TEMPLATE, /* a template is presumed to be always linked */
    IBL_LINK_STATE_END
} ibl_entry_point_type_t;

/* we should allow for all {{bb,trace} x {ret,ind call, ind jmp} x {shared, private}} */
/* combinations of routines which are in turn  x {unlinked, linked} */
typedef enum {
    /* FIXME: have a separate flag for private vs shared */
    IBL_BB_SHARED, 
    IBL_SOURCE_TYPE_START = IBL_BB_SHARED,
    IBL_TRACE_SHARED,
    IBL_BB_PRIVATE,
    IBL_TRACE_PRIVATE,
    IBL_COARSE_SHARED, /* no coarse private, for now */
    IBL_SOURCE_TYPE_END
} ibl_source_fragment_type_t;

#define DEFAULT_IBL_BB() \
{'fraction_non_alphanumeric': 0.10854379365932294, 'fraction_numerical': 0.017971222162517165, 'mean_word_length': 4.676042019654354, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4462466', 'n_tokens_mistral': 5997, 'n_tokens_neox': 5575, 'n_words': 1555}