// The OS/K Team licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #include #include #include #include #include #define log printf #define vlog vprintf #define packed __attribute__ ((__packed__)) #define static_assert _Static_assert #define alignof _Alignof typedef unsigned int bool; typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef struct reg_t reg_t; typedef struct ctx_t ctx_t; typedef struct instr_t instr_t; typedef struct acc_t acc_t; typedef struct arch_t arch_t; enum { RAX, RBX, RCX, RDX, RDI, RSI, RBP, RSP, R8, R9, R10, R11, R12, R13, R14, R15, K0, K1, K2, K3, K4, K5, K6, K7, CR0, CR1, CR2, CR3, CR4, CR5, CR6, CR7, RIP, FLG, NREGS }; enum { GPR = 1 << 0, // General CTL = 1 << 1, // Control SEG = 1 << 2, // Segment RES = 1 << 8, // Reserved for insternal use SYS = 1 << 9, // Reserved for supervisor mode }; // FLG register enum { CF = 1 << 0, // Carry flag PF = 1 << 1, // Parity flag AC = 1 << 2, // Auxiliary flag ZF = 1 << 3, // Zero flag OV = 1 << 4, // Overflow flag DF = 1 << 5, // Direction flag SF = 1 << 6, // Sign flag UF = 1 << 16, // User-mode flag IF = 1 << 17, // Interrupts enable flag }; struct reg_t { char *name; char *desc; ulong val; ulong flags; }; // A_REG is implicit // A_MEM denotes a memory access // A_OFF is A_MEM but a 16-bit offset is expected immediatly next enum { A_REG=0, A_MEM=0x7000, A_OFF, A_IMM16, A_IMM32, A_IMM64 }; struct acc_t { bool mem; // A_MEM? uint type; ulong val; short off; }; enum { NOPREF, PREF_REP=0x8000, PREF_LOCK, NPREFS }; #define ISPREF(x) ((x) & 0x8000 && (x) 0) { _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real); } if (addr < MEMOFF || real >= MEMSIZE) { _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real); } ulong val = (ulong)ctx->mp[real++]; val = (val << 16) | (ulong)ctx->mp[real++]; val = (val << 16) | (ulong)ctx->mp[real++]; val = (val << 16) | (ulong)ctx->mp[real++]; return val; } static inline void writemem64(ctx_t *ctx, ulong val, ulong addr) { ulong real = addr2real(addr); if (addr % alignof(ulong) > 0) { _except(ctx, E_ALI, "Non-aligned memory access: 0x%012lX(0x%012lX)", addr, real); } if (addr < MEMOFF || real >= MEMSIZE) { _except(ctx, E_ACC, "Invalid MEM access: 0x%012lX(0x%012lX)", addr, real); } ctx->mp[real++] = val >> 48; ctx->mp[real++] = (val >> 32) & 0xFFFF; ctx->mp[real++] = (val >> 16) & 0xFFFF; ctx->mp[real++] = val & 0xFFFF; } #include "arch_i.h"