Empty bochs instrument crash in linux, but not in mac
2014-12-25
Empty bochs instrument crash in linux, but not in mac. My instrument code is nearly empty.
core dump:
(gdb) bt #0 0x0000000002dd3af0 in log () #1 0x00007f3977535257 in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #2 0x00007f3977a204fb in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #3 0x00007f3977a2e24d in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #4 0x00007f3977543e2c in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #5 0x00007f39778164a9 in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #6 0x00007f39777f4618 in ?? () from /usr/lib/nvidia-331-updates/libnvidia-glcore.so.331.38 #7 0x00007f3978d939e9 in ?? () from /usr/lib/nvidia-331-updates/libGL.so.1 #8 0x00007f3978dc09d7 in ?? () from /usr/lib/nvidia-331-updates/libGL.so.1 #9 0x00007f3978dc4aac in ?? () from /usr/lib/nvidia-331-updates/libGL.so.1 #10 0x00007f3978dbbad1 in glXCreateContext () from /usr/lib/nvidia-331-updates/libGL.so.1 #11 0x00007f397f92d092 in X11_GL_InitExtensions (_this=0x40ea130) at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11opengl.c:335 #12 X11_GL_LoadLibrary (_this=0x40ea130, path=<optimized out>) at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/x11/SDL_x11opengl.c:218 #13 0x00007f397f921be6 in SDL_GL_LoadLibrary_REAL (path=path@entry=0x0) at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/SDL_video.c:2398 #14 0x00007f397f92377c in SDL_CreateWindow_REAL (title=title@entry=0x7f397f945e3a "OpenGL test", x=x@entry=-32, y=y@entry=-32, w=w@entry=32, h=h@entry=32, flags=flags@entry=10) at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/SDL_video.c:1237 #15 0x00007f397f923490 in ShouldUseTextureFramebuffer () at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/SDL_video.c:189 #16 SDL_VideoInit_REAL (driver_name=<optimized out>, driver_name@entry=0x0) at /build/buildd/libsdl2-2.0.2+dfsg1/src/video/SDL_video.c:503 #17 0x00007f397f88e4ff in SDL_InitSubSystem_REAL (flags=16416) at /build/buildd/libsdl2-2.0.2+dfsg1/src/SDL.c:173 #18 0x000000000052e2c1 in libsdl2_LTX_plugin_init () #19 0x0000000000450000 in load_and_init_display_lib() () #20 0x000000000045130d in bx_begin_simulation(int, char**) () #21 0x000000000052b3a1 in bx_config_interface(int) [clone .constprop.20] () #22 0x000000000052b465 in ci_callback(void*, ci_command_t) () #23 0x0000000000521491 in bx_real_sim_c::configuration_interface(char const*, ci_command_t) () #24 0x000000000044fdf8 in bxmain() () #25 0x00007f397ea93ec5 in __libc_start_main (main=0x44c7b0 <main>, argc=4, argv=0x7fffe418cfb8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffe418cfa8) at libc-start.c:287 #26 0x000000000044d083 in _start ()
configure:
CXXFLAGS=-O3 ./configure --prefix=/toolchain/ --enable-debugger --enable-disasm --disable-debugger-gui --with-rfb --disable-readline --with-sdl2 --enable-all-optimizations --enable-fpu --enable-show-ips --enable-instrumentation="instrument/gkd"
run by:
/toolchain/bin/bochs -q -f bochsrcSDL.bxrc
bochsrcSDL.bxrc:
############################################################### # bochsrc.txt file for DLX Linux disk image. ############################################################### # how much memory the emulated machine will have megs: 32 # filename of ROM images romimage: file=$BXSHARE/BIOS-bochs-latest vgaromimage: file=$BXSHARE/VGABIOS-lgpl-latest # what disk images will be used #floppya: 1_44=../bootimage, status=inserted #floppyb: 1_44=floppyb.img, status=inserted # hard disk #ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 #ata0-master: type=disk, path="hd10meg.img", cylinders=306, heads=4, spt=17 ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 #ata0-master: type=disk, path="10mb.img", mode=flat, cylinders=20, heads=16, spt=63 ata0-master: type=disk, path="../hd.img", mode=flat, cylinders=40, heads=16, spt=63 #ata0-master: type=disk, path="../hd.img", mode=flat, cylinders=203, heads=16, spt=63 # 100MB #ata0-master: type=disk, path="../harddisk", mode=flat, cylinders=2080, heads=16, spt=63 # 1GB # choose the boot disk. boot: c #display_library: term # other choices: win32 sdl wx carbon amigaos beos macintosh nogui rfb term svga display_library: sdl2 # where do we send log messages? log: bochsout.txt # disable the mouse, since DLX is text only mouse: enabled=0 # enable key mapping, using US layout as default. # # NOTE: In Bochs 1.4, keyboard mapping is only 100% implemented on X windows. # However, the key mapping tables are used in the paste function, so # in the DLX Linux example I'm enabling keyboard_mapping so that paste # will work. Cut&Paste is currently implemented on win32 and X windows only. #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-us.map #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-fr.map #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-de.map #keyboard_mapping: enabled=1, map=$BXSHARE/keymaps/x11-pc-es.map magic_break: enabled=1
instrument.h:
///////////////////////////////////////////////////////////////////////// // $Id: instrument.h 11908 2013-10-23 21:18:19Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2006-2012 Stanislav Shwartsman // Written by Stanislav Shwartsman [sshwarts at sourceforge net] // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #if BX_INSTRUMENTATION class bxInstruction_c; // define if you want to store instruction opcode bytes in bxInstruction_c #define BX_INSTR_STORE_OPCODE_BYTES void bx_instr_init_env(void); void bx_instr_exit_env(void); void bx_instr_initialize(unsigned cpu); // maximum size of an instruction #define MAX_OPCODE_LENGTH 16 // maximum physical addresses an instruction can generate #define MAX_DATA_ACCESSES 1024 class bxInstrumentation { public: bx_bool ready; // is current instruction ready to be printed bx_bool active; unsigned cpu_id; /* decoding */ unsigned opcode_length; Bit8u opcode[MAX_OPCODE_LENGTH]; bx_bool is32, is64; /* memory accesses */ unsigned num_data_accesses; struct { bx_address laddr; // linear address bx_phy_address paddr; // physical address unsigned rw; // BX_READ, BX_WRITE or BX_RW unsigned size; // 1 .. 32 } data_access[MAX_DATA_ACCESSES]; /* branch resolution and target */ bx_bool is_branch; bx_bool is_taken; bx_address target_linear; public: bxInstrumentation(): ready(0), active(0) {} void set_cpu_id(unsigned cpu) { cpu_id = cpu; } void activate() { active = 1; } void deactivate() { active = 0; } void toggle_active() { active = !active; } bx_bool is_active() const { return active; } void bx_instr_reset(unsigned type); void bx_instr_cnear_branch_taken(bx_address branch_eip, bx_address new_eip); void bx_instr_cnear_branch_not_taken(bx_address branch_eip); void bx_instr_ucnear_branch(unsigned what, bx_address branch_eip, bx_address new_eip); void bx_instr_far_branch(unsigned what, Bit16u new_cs, bx_address new_eip); void bx_instr_before_execution(bxInstruction_c *i); void bx_instr_after_execution(bxInstruction_c *i); void bx_instr_interrupt(unsigned vector); void bx_instr_exception(unsigned vector, unsigned error_code); void bx_instr_hwinterrupt(unsigned vector, Bit16u cs, bx_address eip); void bx_instr_lin_access(bx_address lin, bx_phy_address phy, unsigned len, unsigned rw); void memorySampling(bx_phy_address); void jmpSampling(bx_address); private: void branch_taken(bx_address new_eip); void bx_print_instruction(void); }; void bx_instr_init(unsigned cpu); extern bxInstrumentation *icpu; /* initialization/deinitialization of instrumentalization*/ #define BX_INSTR_INIT_ENV() bx_instr_init_env() #define BX_INSTR_EXIT_ENV() bx_instr_exit_env() /* simulation init, shutdown, reset */ #define BX_INSTR_INITIALIZE(cpu_id) bx_instr_initialize(cpu_id) #define BX_INSTR_EXIT(cpu_id) #define BX_INSTR_RESET(cpu_id, type) icpu[cpu_id].bx_instr_reset(type) #define BX_INSTR_HLT(cpu_id) #define BX_INSTR_MWAIT(cpu_id, addr, len, flags) /* called from command line debugger */ #define BX_INSTR_DEBUG_PROMPT() #define BX_INSTR_DEBUG_CMD(cmd) /* branch resolution */ #define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip) icpu[cpu_id].bx_instr_cnear_branch_taken(branch_eip, new_eip) #define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip) icpu[cpu_id].bx_instr_cnear_branch_not_taken(branch_eip) #define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip) icpu[cpu_id].bx_instr_ucnear_branch(what, branch_eip, new_eip) #define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip) icpu[cpu_id].bx_instr_far_branch(what, new_cs, new_eip) /* decoding completed */ #define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64) /* exceptional case and interrupt */ #define BX_INSTR_EXCEPTION(cpu_id, vector, error_code) \ icpu[cpu_id].bx_instr_exception(vector, error_code) #define BX_INSTR_INTERRUPT(cpu_id, vector) icpu[cpu_id].bx_instr_interrupt(vector) #define BX_INSTR_HWINTERRUPT(cpu_id, vector, cs, eip) icpu[cpu_id].bx_instr_hwinterrupt(vector, cs, eip) /* TLB/CACHE control instruction executed */ #define BX_INSTR_CLFLUSH(cpu_id, laddr, paddr) #define BX_INSTR_CACHE_CNTRL(cpu_id, what) #define BX_INSTR_TLB_CNTRL(cpu_id, what, new_cr3) #define BX_INSTR_PREFETCH_HINT(cpu_id, what, seg, offset) /* execution */ #define BX_INSTR_BEFORE_EXECUTION(cpu_id, i) icpu[cpu_id].bx_instr_before_execution(i) #define BX_INSTR_AFTER_EXECUTION(cpu_id, i) icpu[cpu_id].bx_instr_after_execution(i) #define BX_INSTR_REPEAT_ITERATION(cpu_id, i) /* memory access */ #define BX_INSTR_LIN_ACCESS(cpu_id, lin, phy, len, rw) \ icpu[cpu_id].bx_instr_lin_access(lin, phy, len, rw) #define BX_INSTR_PHY_ACCESS(cpu_id, phy, len, rw) /* feedback from device units */ #define BX_INSTR_INP(addr, len) #define BX_INSTR_INP2(addr, len, val) #define BX_INSTR_OUTP(addr, len, val) /* wrmsr callback */ #define BX_INSTR_WRMSR(cpu_id, addr, value) /* vmexit callback */ #define BX_INSTR_VMEXIT(cpu_id, reason, qualification) #else // BX_INSTRUMENTATION /* initialization/deinitialization of instrumentalization */ #define BX_INSTR_INIT_ENV() #define BX_INSTR_EXIT_ENV() /* simulation init, shutdown, reset */ #define BX_INSTR_INITIALIZE(cpu_id) #define BX_INSTR_EXIT(cpu_id) #define BX_INSTR_RESET(cpu_id, type) #define BX_INSTR_HLT(cpu_id) #define BX_INSTR_MWAIT(cpu_id, addr, len, flags) /* called from command line debugger */ #define BX_INSTR_DEBUG_PROMPT() #define BX_INSTR_DEBUG_CMD(cmd) /* branch resolution */ #define BX_INSTR_CNEAR_BRANCH_TAKEN(cpu_id, branch_eip, new_eip) #define BX_INSTR_CNEAR_BRANCH_NOT_TAKEN(cpu_id, branch_eip) #define BX_INSTR_UCNEAR_BRANCH(cpu_id, what, branch_eip, new_eip) #define BX_INSTR_FAR_BRANCH(cpu_id, what, new_cs, new_eip) /* decoding completed */ #define BX_INSTR_OPCODE(cpu_id, i, opcode, len, is32, is64) /* exceptional case and interrupt */ #define BX_INSTR_EXCEPTION(cpu_id, vector, error_code) #define BX_INSTR_INTERRUPT(cpu_id, vector) #define BX_INSTR_HWINTERRUPT(cpu_id, vector, cs, eip) /* TLB/CACHE control instruction executed */ #define BX_INSTR_CLFLUSH(cpu_id, laddr, paddr) #define BX_INSTR_CACHE_CNTRL(cpu_id, what) #define BX_INSTR_TLB_CNTRL(cpu_id, what, new_cr3) #define BX_INSTR_PREFETCH_HINT(cpu_id, what, seg, offset) /* execution */ #define BX_INSTR_BEFORE_EXECUTION(cpu_id, i) #define BX_INSTR_AFTER_EXECUTION(cpu_id, i) #define BX_INSTR_REPEAT_ITERATION(cpu_id, i) /* linear memory access */ #define BX_INSTR_LIN_ACCESS(cpu_id, lin, phy, len, rw) /* physical memory access */ #define BX_INSTR_PHY_ACCESS(cpu_id, phy, len, rw) /* feedback from device units */ #define BX_INSTR_INP(addr, len) #define BX_INSTR_INP2(addr, len, val) #define BX_INSTR_OUTP(addr, len, val) /* wrmsr callback */ #define BX_INSTR_WRMSR(cpu_id, addr, value) /* vmexit callback */ #define BX_INSTR_VMEXIT(cpu_id, reason, qualification) #endif // BX_INSTRUMENTATION
instrument.cc:
///////////////////////////////////////////////////////////////////////// // $Id: instrument.cc 11908 2013-10-23 21:18:19Z sshwarts $ ///////////////////////////////////////////////////////////////////////// // // Copyright (c) 2006-2012 Stanislav Shwartsman // Written by Stanislav Shwartsman [sshwarts at sourceforge net] // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include <assert.h> #include "bochs.h" #include "cpu/cpu.h" #include "disasm/disasm.h" #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <netinet/tcp.h> #include <fstream> using namespace std; #include <set> using std::set; #define GKD_INSTRUMENT_VERSION "20141215" int memorySockfd; int jmpSockfd; int interruptSockfd; int memoryPortNo = 1980; int jmpPortNo = 1981; int interruptPortNo = 1982; int oslogPort = 0xffff; char oslogFile[] = "os.log"; ofstream oslogStream(oslogFile, ios::app); #define printHeader bxInstrumentation *icpu = NULL; static disassembler bx_disassembler; #define MAX_SEND_BYTE 500 FILE *log; unsigned int zonesFrom[MAX_SEND_BYTE]; unsigned int zonesTo[MAX_SEND_BYTE]; unsigned int zonesHit[MAX_SEND_BYTE]; unsigned int zonesTail = 0; set<unsigned int> zonesHitAddress[MAX_SEND_BYTE]; bx_bool connectedToMemoryServer; bx_bool connectedToJmpServer; bx_bool connectedToInterruptServer; bx_bool triedToContectToServer; bx_address startRecordJumpAddress = 0x7c00; bx_bool startRecordJump; bx_address segmentBegin = startRecordJumpAddress; bx_address segmentEnd; void logPeterBochs(char *str) { fprintf(log, str); fflush(log); } void logPeterBochs(char *str1, char *str2, char *str3) { fprintf(log, str1); fprintf(log, str2); fprintf(log, str3); fflush(log); } void logPeterBochs(unsigned int x) { char temp[100]; sprintf(temp, "%x\n", x); fprintf(log, temp); fflush(log); } void logPeterBochs(char *a, unsigned int x, char *b) { fprintf(log, a); char temp[100]; sprintf(temp, "%u", x); fprintf(log, temp); fprintf(log, b); fflush(log); } unsigned int convert(unsigned char *inBuffer) { return inBuffer[3] + (inBuffer[2] << 8) + (inBuffer[1] << 16) + (inBuffer[0] << 24); } void safeRead(int socketFD, unsigned char *inBuffer, unsigned int size) { int noOfBytes = 0; while (noOfBytes != size) { noOfBytes += read(socketFD, inBuffer + noOfBytes, size - noOfBytes); } } void initMemorySocket() { /* oslogStream << "initMemorySocket" << endl; oslogStream.flush(); memorySockfd = socket(AF_INET, SOCK_STREAM, 0); if (memorySockfd < 0) { //fprintf(stderr, "ERROR opening socket\n"); fprintf(log, "Memory socket server : ERROR opening socket\n"); return; } struct sockaddr_in serv_addr; struct hostent *server; server = gethostbyname("localhost"); if (server == NULL) { //fprintf(stderr, "ERROR, no such host\n"); fprintf(log, "Memory socket server : ERROR no such host\n"); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(memoryPortNo); if (connect(memorySockfd, (const sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fprintf(log, "Memory socket server : ERROR connecting\n"); connectedToMemoryServer = false; } else { fprintf(log, "Memory socket server : connected to server\n"); connectedToMemoryServer = true; } int flag = 1; int ret = setsockopt(memorySockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)); if (ret == -1) { fprintf(log, "memorySockfd couldn't setsockopt(TCP_NODELAY)\n"); } fflush(log); oslogStream << "initMemorySocket2" << endl; oslogStream.flush(); */ } void initJmpSocket() { /* jmpSockfd = socket(AF_INET, SOCK_STREAM, 0); if (jmpSockfd < 0) { fprintf(log, "Jmp socket server : ERROR opening socket\n"); return; } struct sockaddr_in serv_addr; struct hostent *server; server = gethostbyname("localhost"); if (server == NULL) { fprintf(log, "Jmp socket server : ERROR no such host\n"); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(jmpPortNo); if (connect(jmpSockfd, (const sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fprintf(log, "Jmp socket server : ERROR connecting\n"); connectedToJmpServer = false; } else { fprintf(log, "Jmp socket server : connected to server\n"); connectedToJmpServer = true; } int flag = 1; int ret = setsockopt(jmpSockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)); if (ret == -1) { fprintf(log, "jmpSockfd couldn't setsockopt(TCP_NODELAY)\n"); } if (connectedToJmpServer) { } fflush(log); */ } void initInterruptSocket() { /* interruptSockfd = socket(AF_INET, SOCK_STREAM, 0); if (interruptSockfd < 0) { fprintf(log, "Interrupt socket server : ERROR opening socket\n"); return; } struct sockaddr_in serv_addr; struct hostent *server; server = gethostbyname("localhost"); if (server == NULL) { fprintf(log, "Interrupt socket server : ERROR no such host\n"); } bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(interruptPortNo); if (connect(interruptSockfd, (const sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { fprintf(log, "Interrupt socket server : ERROR connecting\n"); connectedToInterruptServer = false; } else { fprintf(log, "Interrupt socket server : connected to server\n"); connectedToInterruptServer = true; } int flag = 1; int ret = setsockopt(interruptSockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag)); if (ret == -1) { fprintf(log, "interruptSockfd couldn't setsockopt(TCP_NODELAY)\n"); } if (connectedToInterruptServer) { } fflush(log); */ } void bx_instr_init_env(void) { } void bx_instr_exit_env(void) { } void bx_instr_initialize(unsigned cpu) { /* assert(cpu < BX_SMP_PROCESSORS); if (icpu == NULL) icpu = new bxInstrumentation[BX_SMP_PROCESSORS]; icpu[cpu].set_cpu_id(cpu); fprintf(stderr, "Initialize cpu %d\n", cpu); // GKD log = fopen("gkd.log", "a+"); fprintf(stderr, "GKD instrument %s - Initialize cpu %d\n", GKD_INSTRUMENT_VERSION, cpu); if (connectedToMemoryServer) { for (int x = 0; x < MAX_SEND_BYTE; x++) { zonesFrom[x] = -1; zonesTo[x] = -1; zonesHit[x] = 0; } } */ } void bxInstrumentation::bx_instr_reset(unsigned type) { /* ready = is_branch = 0; num_data_accesses = 0; active = 1; */ } void bxInstrumentation::bx_print_instruction(void) { /* char disasm_tbuf[512]; // buffer for instruction disassembly bx_disassembler.disasm(is32, is64, 0, 0, opcode, disasm_tbuf); if (opcode_length != 0) { unsigned n; //fprintf(stderr, "----------------------------------------------------------\n"); printf("CPU: %d: %s\n", cpu_id, disasm_tbuf); //fprintf(stderr, "LEN: %d\tBYTES: ", opcode_length); for (n = 0; n < opcode_length; n++) //fprintf(stderr, "%02x", opcode[n]); if (is_branch) { //fprintf(stderr, "\tBRANCH "); if (is_taken) { //fprintf(stderr, "TARGET " FMT_ADDRX " (TAKEN)", target_linear); } else { //fprintf(stderr, "(NOT TAKEN)"); } } //fprintf(stderr, "\n"); if (connectedToMemoryServer) { for (n = 0; n < num_data_accesses; n++) { fprintf(stderr, "MEM ACCESS[%u]: 0x" FMT_ADDRX " (linear) 0x" FMT_PHY_ADDRX " (physical) %s SIZE: %d\n", n, data_access[n].laddr, data_access[n].paddr, data_access[n].op == BX_READ ? "RD":"WR", data_access[n].size); //memorySampling(data_access[n].paddr, data_access[n].eip); } } //fprintf(stderr, "\n"); } */ } void bxInstrumentation::bx_instr_before_execution(bxInstruction_c *i) { /* if (!active) return; if (ready) bx_print_instruction(); if (!triedToContectToServer) { initMemorySocket(); initJmpSocket(); initInterruptSocket(); triedToContectToServer = true; } // prepare instruction_t structure for new instruction ready = 1; num_data_accesses = 0; is_branch = 0; is32 = BX_CPU(cpu_id)->sregs[BX_SEG_REG_CS].cache.u.segment.d_b; is64 = BX_CPU(cpu_id)->long64_mode(); opcode_length = i->ilen(); memcpy(opcode, i->get_opcode_bytes(), opcode_length); bx_phy_address phyAddress = BX_CPU(cpu_id)->get_instruction_pointer(); segmentEnd = phyAddress; if (phyAddress == startRecordJumpAddress) { startRecordJump = true; } */ } void bxInstrumentation::bx_instr_after_execution(bxInstruction_c *i) { /* if (!active) return; if (ready) { bx_print_instruction(); ready = 0; } */ } void bxInstrumentation::branch_taken(bx_address new_eip) { /* if (!active || !ready) return; // find linear address bx_address laddr = BX_CPU(cpu_id)->get_laddr(BX_SEG_REG_CS, new_eip); is_branch = 1; is_taken = 1; target_linear = laddr; */ printf("branch_taken=%x\n",new_eip); } void bxInstrumentation::bx_instr_cnear_branch_taken(bx_address branch_eip, bx_address new_eip) { /* branch_taken(new_eip); if (connectedToJmpServer) { jmpSampling(new_eip); } */ printf("bx_instr_cnear_branch_taken=%x, %x\n",branch_eip, new_eip); } void bxInstrumentation::bx_instr_cnear_branch_not_taken(bx_address branch_eip) { /* if (!active || !ready) return; is_branch = 1; is_taken = 0; */ printf("bx_instr_cnear_branch_not_taken=%x\n",branch_eip); } void bxInstrumentation::bx_instr_ucnear_branch(unsigned what, bx_address branch_eip, bx_address new_eip) { /* branch_taken(new_eip); if (connectedToJmpServer) { jmpSampling(new_eip); } */ printf("bx_instr_ucnear_branch=%x, %x\n",branch_eip, new_eip); } void bxInstrumentation::bx_instr_far_branch(unsigned what, Bit16u new_cs, bx_address new_eip) { /* branch_taken(new_eip); if (connectedToJmpServer) { jmpSampling(new_eip); } */ } void bxInstrumentation::bx_instr_interrupt(unsigned vector) { /* if (active) { //fprintf(stderr, "CPU %u: interrupt %02xh\n", cpu_id, vector); if (connectedToInterruptServer) { write(interruptSockfd, &vector, sizeof(vector)); } } */ } void bxInstrumentation::bx_instr_exception(unsigned vector, unsigned error_code) { if (active) { //fprintf(stderr, "CPU %u: exception %02xh error_code=%x\n", cpu_id, vector, error_code); } } void bxInstrumentation::bx_instr_hwinterrupt(unsigned vector, Bit16u cs, bx_address eip) { if (active) { //fprintf(stderr, "CPU %u: hardware interrupt %02xh\n", cpu_id, vector); } } void bxInstrumentation::bx_instr_lin_access(bx_address lin, bx_phy_address phy, unsigned len, unsigned rw) { /* if (!active || !ready) return; if (num_data_accesses >= MAX_DATA_ACCESSES) { return; } //bx_address lin = BX_CPU(cpu)->get_laddr(seg, offset); bx_bool page_valid = BX_CPU(cpu)->dbg_xlate_linear2phy(lin, &phy); phy = A20ADDR(phy); // If linear translation doesn't exist, a paging exception will occur. // Invalidate physical address data for now. if (!page_valid) phy = (bx_phy_address) (-1); data_access[num_data_accesses].laddr = lin; data_access[num_data_accesses].paddr = phy; data_access[num_data_accesses].rw = rw; data_access[num_data_accesses].size = len; num_data_accesses++; if (connectedToMemoryServer) { memorySampling(phy); } */ } unsigned int buffer[MAX_SEND_BYTE]; int pointer = 0; void bxInstrumentation::memorySampling(bx_phy_address paddr) { /* if (!connectedToMemoryServer) { return; } buffer[pointer] = paddr; pointer++; // check zone for (int x = 0; x < zonesTail; x++) { if (zonesFrom[x] <= paddr && paddr <= zonesTo[x]) { zonesHit[x]++; zonesHitAddress[x].insert(paddr); } } // end check zone if (pointer == MAX_SEND_BYTE) { send(memorySockfd, (char *) buffer, MAX_SEND_BYTE * sizeof(unsigned int), 0); send(memorySockfd, &zonesTail, sizeof(unsigned int), 0); for (int x = 0; x < zonesTail; x++) { write(memorySockfd, &zonesFrom[x], sizeof(unsigned int)); write(memorySockfd, &zonesTo[x], sizeof(unsigned int)); write(memorySockfd, &zonesHit[x], sizeof(unsigned int)); unsigned int size; if (zonesHitAddress[x].size() < 10) { size = zonesHitAddress[x].size(); } else { size = 10; } //noOfZoneHitAddress write(memorySockfd, &size, sizeof(unsigned int)); set<unsigned int>::iterator theIterator; int yy = 0; for (theIterator = zonesHitAddress[x].begin(); theIterator != zonesHitAddress[x].end() && yy < size; theIterator++) { write(memorySockfd, &*theIterator, sizeof(unsigned int)); yy++; } } // end send zones back to GKD unsigned char inBuffer[10000]; safeRead(memorySockfd, inBuffer, 1); if (inBuffer[0] == 2) { safeRead(memorySockfd, inBuffer, 4); unsigned int noOfData = convert(inBuffer); int readSize = noOfData * sizeof(unsigned int) * 2; safeRead(memorySockfd, inBuffer, readSize); int offset = 0; for (int x = 0; x < noOfData; x++) { unsigned int from = convert(&inBuffer[offset]); zonesFrom[x] = from; offset += 4; unsigned int to = convert(&inBuffer[offset]); zonesTo[x] = to; offset += 4; } zonesTail = noOfData; } pointer = 0; } */ } void bxInstrumentation::jmpSampling(bx_address new_eip) { /* if (connectedToJmpServer) { if (startRecordJump) { write(jmpSockfd, &new_eip, sizeof(bx_address)); write(jmpSockfd, &new_eip, sizeof(bx_address)); write(jmpSockfd, &segmentBegin, sizeof(segmentBegin)); write(jmpSockfd, &segmentEnd, sizeof(segmentBegin)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_EAX].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_ECX].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_EDX].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_EBX].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_ESP].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_EBP].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_ESI].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->gen_reg[BX_32BIT_REG_EDI].dword.erx, sizeof(Bit32u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_ES].selector.value, sizeof(Bit16u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_CS].selector.value, sizeof(Bit16u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_SS].selector.value, sizeof(Bit16u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_DS].selector.value, sizeof(Bit16u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_FS].selector.value, sizeof(Bit16u)); write(jmpSockfd, &BX_CPU(0)->sregs[BX_SEG_REG_GS].selector.value, sizeof(Bit16u)); segmentBegin = new_eip; } } */ }