Home | History | Annotate | Download | only in pub
      1 
      2 /*---------------------------------------------------------------*/
      3 /*--- begin                              libvex_guest_amd64.h ---*/
      4 /*---------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2017 OpenWorks LLP
     11       info (at) open-works.net
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     26    02110-1301, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 
     30    Neither the names of the U.S. Department of Energy nor the
     31    University of California nor the names of its contributors may be
     32    used to endorse or promote products derived from this software
     33    without prior written permission.
     34 */
     35 
     36 #ifndef __LIBVEX_PUB_GUEST_AMD64_H
     37 #define __LIBVEX_PUB_GUEST_AMD64_H
     38 
     39 #include "libvex_basictypes.h"
     40 #include "libvex_emnote.h"
     41 
     42 
     43 /*---------------------------------------------------------------*/
     44 /*--- Vex's representation of the AMD64 CPU state.            ---*/
     45 /*---------------------------------------------------------------*/
     46 
     47 /* See detailed comments at the top of libvex_guest_x86.h for
     48    further info.  This representation closely follows the
     49    x86 representation.
     50 */
     51 
     52 
     53 typedef
     54    struct {
     55       /* Event check fail addr, counter, and padding to make RAX 16
     56          aligned. */
     57       /*   0 */ ULong  host_EvC_FAILADDR;
     58       /*   8 */ UInt   host_EvC_COUNTER;
     59       /*  12 */ UInt   pad0;
     60       /*  16 */ ULong  guest_RAX;
     61       /*  24 */ ULong  guest_RCX;
     62       /*  32 */ ULong  guest_RDX;
     63       /*  40 */ ULong  guest_RBX;
     64       /*  48 */ ULong  guest_RSP;
     65       /*  56 */ ULong  guest_RBP;
     66       /*  64 */ ULong  guest_RSI;
     67       /*  72 */ ULong  guest_RDI;
     68       /*  80 */ ULong  guest_R8;
     69       /*  88 */ ULong  guest_R9;
     70       /*  96 */ ULong  guest_R10;
     71       /* 104 */ ULong  guest_R11;
     72       /* 112 */ ULong  guest_R12;
     73       /* 120 */ ULong  guest_R13;
     74       /* 128 */ ULong  guest_R14;
     75       /* 136 */ ULong  guest_R15;
     76       /* 4-word thunk used to calculate O S Z A C P flags. */
     77       /* 144 */ ULong  guest_CC_OP;
     78       /* 152 */ ULong  guest_CC_DEP1;
     79       /* 160 */ ULong  guest_CC_DEP2;
     80       /* 168 */ ULong  guest_CC_NDEP;
     81       /* The D flag is stored here, encoded as either -1 or +1 */
     82       /* 176 */ ULong  guest_DFLAG;
     83       /* 184 */ ULong  guest_RIP;
     84       /* Bit 18 (AC) of eflags stored here, as either 0 or 1. */
     85       /* ... */ ULong  guest_ACFLAG;
     86       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
     87       /* 192 */ ULong guest_IDFLAG;
     88       /* Probably a lot more stuff too.
     89          D,ID flags
     90          16  128-bit SSE registers
     91          all the old x87 FPU gunk
     92          segment registers */
     93 
     94       /* HACK to e.g. make tls on amd64-linux/solaris work.  %fs only ever seems
     95          to hold a constant value (zero on linux main thread, 0x63 in other
     96          threads), and so guest_FS_CONST holds
     97          the 64-bit offset associated with this constant %fs value. */
     98       /* 200 */ ULong guest_FS_CONST;
     99 
    100       /* YMM registers.  Note that these must be allocated
    101          consecutively in order that the SSE4.2 PCMP{E,I}STR{I,M}
    102          helpers can treat them as an array.  YMM16 is a fake reg used
    103          as an intermediary in handling aforementioned insns. */
    104       /* 208 */ULong guest_SSEROUND;
    105       /* 216 */U256  guest_YMM0;
    106       U256  guest_YMM1;
    107       U256  guest_YMM2;
    108       U256  guest_YMM3;
    109       U256  guest_YMM4;
    110       U256  guest_YMM5;
    111       U256  guest_YMM6;
    112       U256  guest_YMM7;
    113       U256  guest_YMM8;
    114       U256  guest_YMM9;
    115       U256  guest_YMM10;
    116       U256  guest_YMM11;
    117       U256  guest_YMM12;
    118       U256  guest_YMM13;
    119       U256  guest_YMM14;
    120       U256  guest_YMM15;
    121       U256  guest_YMM16;
    122 
    123       /* FPU */
    124       /* Note.  Setting guest_FTOP to be ULong messes up the
    125          delicately-balanced PutI/GetI optimisation machinery.
    126          Therefore best to leave it as a UInt. */
    127       UInt  guest_FTOP;
    128       UInt  pad1;
    129       ULong guest_FPREG[8];
    130       UChar guest_FPTAG[8];
    131       ULong guest_FPROUND;
    132       ULong guest_FC3210;
    133 
    134       /* Emulation notes */
    135       UInt  guest_EMNOTE;
    136       UInt  pad2;
    137 
    138       /* Translation-invalidation area description.  Not used on amd64
    139          (there is no invalidate-icache insn), but needed so as to
    140          allow users of the library to uniformly assume that the guest
    141          state contains these two fields -- otherwise there is
    142          compilation breakage.  On amd64, these two fields are set to
    143          zero by LibVEX_GuestAMD64_initialise and then should be
    144          ignored forever thereafter. */
    145       ULong guest_CMSTART;
    146       ULong guest_CMLEN;
    147 
    148       /* Used to record the unredirected guest address at the start of
    149          a translation whose start has been redirected.  By reading
    150          this pseudo-register shortly afterwards, the translation can
    151          find out what the corresponding no-redirection address was.
    152          Note, this is only set for wrap-style redirects, not for
    153          replace-style ones. */
    154       ULong guest_NRADDR;
    155 
    156       /* Used for Darwin syscall dispatching. */
    157       ULong guest_SC_CLASS;
    158 
    159       /* HACK to make e.g. tls on darwin work, wine on linux work, ...
    160          %gs only ever seems to hold a constant value (e.g. 0x60 on darwin,
    161          0x6b on linux), and so guest_GS_CONST holds the 64-bit offset
    162          associated with this constant %gs value.  (A direct analogue
    163          of the %fs-const hack for amd64-linux/solaris). */
    164       ULong guest_GS_CONST;
    165 
    166       /* Needed for Darwin (but mandated for all guest architectures):
    167          RIP at the last syscall insn (int 0x80/81/82, sysenter,
    168          syscall).  Used when backing up to restart a syscall that has
    169          been interrupted by a signal. */
    170       ULong guest_IP_AT_SYSCALL;
    171 
    172       /* Padding to make it have an 16-aligned size */
    173       ULong pad3;
    174    }
    175    VexGuestAMD64State;
    176 
    177 
    178 
    179 /*---------------------------------------------------------------*/
    180 /*--- Utility functions for amd64 guest stuff.                ---*/
    181 /*---------------------------------------------------------------*/
    182 
    183 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
    184 
    185 /* Initialise all guest amd64 state.  The FPU is put in default
    186    mode. */
    187 extern
    188 void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state );
    189 
    190 
    191 /* Extract from the supplied VexGuestAMD64State structure the
    192    corresponding native %rflags value. */
    193 extern
    194 ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state );
    195 
    196 /* Put rflags into the given state. */
    197 extern
    198 void LibVEX_GuestAMD64_put_rflags ( ULong rflags,
    199                                     /*MOD*/VexGuestAMD64State* vex_state );
    200 
    201 /* Set the carry flag in the given state to 'new_carry_flag', which
    202    should be zero or one. */
    203 extern
    204 void
    205 LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
    206                                 /*MOD*/VexGuestAMD64State* vex_state );
    207 
    208 /* Do FXSAVE from the supplied VexGuestAMD64tate structure and store the
    209    result at the given address which represents a buffer of at least 416
    210    bytes. */
    211 extern
    212 void LibVEX_GuestAMD64_fxsave ( /*IN*/VexGuestAMD64State* gst,
    213                                 /*OUT*/HWord fp_state );
    214 
    215 /* Do FXRSTOR from the supplied address and store read values to the given
    216    VexGuestAMD64State structure. */
    217 extern
    218 VexEmNote LibVEX_GuestAMD64_fxrstor ( /*IN*/HWord fp_state,
    219                                       /*MOD*/VexGuestAMD64State* gst );
    220 
    221 #endif /* ndef __LIBVEX_PUB_GUEST_AMD64_H */
    222 
    223 /*---------------------------------------------------------------*/
    224 /*---                                    libvex_guest_amd64.h ---*/
    225 /*---------------------------------------------------------------*/
    226