Author: eliot Date: 2012-08-10 14:28:50 -0700 (Fri, 10 Aug 2012) New Revision: 2583
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/ trunk/platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile.win32 trunk/platforms/Cross/plugins/GdbARMPlugin/README trunk/platforms/Cross/plugins/GdbARMPlugin/armulmem.c trunk/platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c Modified: trunk/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h Log: Add Lars' GdmArmPlugin support files. Add API call def to SocketPlugin.h
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h =================================================================== --- trunk/platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h (rev 0) +++ trunk/platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h 2012-08-10 21:28:50 UTC (rev 2583) @@ -0,0 +1,70 @@ +/* heavily based on BochsIA32Plugin.h */ +/* Bochs seems to use error code 1 for execution errors. + * So we use > 1 for various errors + */ +#define NoError 0 +#define ExecutionError 1 +#define BadCPUInstance 2 +#define MemoryBoundsError 3 +#define PanicError 4 +#define UnsupportedOperationError 5 +#define SomethingLoggedError 6 + +// The library is compiled with TFlag, therefore, we also need to set it. +#define MODET + +#if !defined(ulong) +typedef unsigned long ulong; +#endif + +extern ulong minReadAddress, minWriteAddress; +extern int gdb_log_printf(void* stream, const char * format, ...); + + +/* + * Answer a pointer to a new ARMulator CPU (an instance of typedef ARMul_State) + */ +extern void *newCPU(); +/* + * reset the cpu to register contents 0, protected 32-bit mode. + */ +extern int resetCPU(void *cpu); +/* + * Single-step *cpu (an ARMul_state instance) using memory as its memory. + * Answer 0 on success, or an integer error code if something went awry. + */ +extern int singleStepCPUInSizeMinAddrReadWrite(void *cpu, void *memory, + ulong byteSize, ulong minReadAddr, ulong minWriteAddr); +/* + * Run *cpu (an ARMul_state instance) using memory as its memory. + * Answer an integer error code when the processor hits some exception. + * Answer 0 when it is interrupted. + */ +extern int runCPUInSizeMinAddrReadWrite(void *cpu, void *memory, + ulong byteSize, ulong minReadAddr, ulong minWriteAddr); +/* + * Flush any icache entries from start to end + */ +extern void flushICacheFromTo(void *cpu, ulong strt, ulong nd); +/* + * force runCPUInSize to exit asap. Used by interrupts. + */ +extern void forceStopRunning(); +/* + * The previous entry in the interruptCheckChain so forceStopRunning can chain. + */ +extern void (*prevInterruptCheckChain)(); +/* + * Disassemble the instruction at address in memory, writing the output to the + * log. + */ +extern int disassembleForAtInSize(void *cpu, ulong laddr, + void *memory, ulong byteSize); +/* + * The saved error if the previous singleStepIn failed. + */ +extern int errorAcorn(); +/* + * The current log (if singleStep failed with SomethingLoggedError). + */ +extern char *getlog(long *len);
Property changes on: trunk/platforms/Cross/plugins/GdbARMPlugin/GdbARMPlugin.h ___________________________________________________________________ Added: svn:executable + *
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile =================================================================== --- trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile (rev 0) +++ trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile 2012-08-10 21:28:50 UTC (rev 2583) @@ -0,0 +1,15 @@ +CC = gcc +CFLAGS = +LDFLAGS = libsim.a $(GDBBUILDFOLDER)/opcodes/libopcodes.a -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI +GDBBUILDFOLDER = /d/build/gdb-7.4 +SHAREDLIBRARYFLAGS = + +all: + $(CC) $(CFLAGS) armulmem.c -c -I$(GDBBUILDFOLDER)/sim/arm/ + $(CC) $(CFLAGS) sqGdbARMPlugin.c -c -fPIC -I$(GDBBUILDFOLDER)/sim/arm/ + gcc -shared $(SHAREDLIBRARYFLAGS) -o GdbARMPlugin.dll sqGdbARMPlugin.o armulmem.o $(LDFLAGS) +# mkdir ../cog/platforms/Cross/plugins/GdbARMPlugin +# mkdir ../cog/platforms/win32/plugins/GdbARMPlugin + cp sqGdbARMPlugin.c GdbARMPlugin.h armulmem.c ../cog/platforms/Cross/plugins/GdbARMPlugin/ + cp Makefile.win32 ../cog/platforms/win32/plugins/GdbARMPlugin/Makefile + cd ../cog/cygwinbuild; make
Property changes on: trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile ___________________________________________________________________ Added: svn:executable + *
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile.win32 =================================================================== --- trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile.win32 (rev 0) +++ trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile.win32 2012-08-10 21:28:50 UTC (rev 2583) @@ -0,0 +1,14 @@ +DLLTOOLEXTRA := /d/Dateien/cog/squeakvm-armulator-plugin/libsim.a \ + /d/build/gdb-7.4/opcodes/libopcodes.a +DLLWRAPEXTRA := $(DLLTOOLEXTRA) + +LINK_WITH_GPP := yes +EXTRALIBS:= -L/d/Dateien/cog/squeakvm-armulator-plugin \ + -L/d/build/gdb-7.4/opcodes \ + -lsim -lopcodes -lbfd -lintl -liberty -Wl,-wrap,ARMul_OSHandleSWI + +include ../../Makefile.plugin + +INCLUDES:= $(INCLUDES) -I/d/build/gdb-7.4/sim/arm + +
Property changes on: trunk/platforms/Cross/plugins/GdbARMPlugin/Makefile.win32 ___________________________________________________________________ Added: svn:executable + *
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/README =================================================================== Added: trunk/platforms/Cross/plugins/GdbARMPlugin/armulmem.c =================================================================== --- trunk/platforms/Cross/plugins/GdbARMPlugin/armulmem.c (rev 0) +++ trunk/platforms/Cross/plugins/GdbARMPlugin/armulmem.c 2012-08-10 21:28:50 UTC (rev 2583) @@ -0,0 +1,506 @@ +/* + This file is a compy of armvirt.c, which is part of the ARMulator distributed e.g. with gdb and skyeye. + In order to overwrite GetWord and PutWord, I had to copy the whole file. + Also changed: ReLoadInstr. +*/ +#include "GdbARMPlugin.h" + +/* armvirt.c -- ARMulator virtual memory interace: ARM6 Instruction Emulator. + Copyright (C) 1994 Advanced RISC Machines Ltd. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* This file contains a complete ARMulator memory model, modelling a +"virtual memory" system. A much simpler model can be found in armfast.c, +and that model goes faster too, but has a fixed amount of memory. This +model's memory has 64K pages, allocated on demand from a 64K entry page +table. The routines PutWord and GetWord implement this. Pages are never +freed as they might be needed again. A single area of memory may be +defined to generate aborts. */ + +#include "armopts.h" +#include "armos.h" +#include "armdefs.h" +#include "ansidecl.h" + +#ifdef VALIDATE /* for running the validate suite */ +#define TUBE 48 * 1024 * 1024 /* write a char on the screen */ +#define ABORTS 1 +#endif + +/* #define ABORTS */ + +#ifdef ABORTS /* the memory system will abort */ +/* For the old test suite Abort between 32 Kbytes and 32 Mbytes + For the new test suite Abort between 8 Mbytes and 26 Mbytes */ +/* #define LOWABORT 32 * 1024 +#define HIGHABORT 32 * 1024 * 1024 */ +#define LOWABORT 8 * 1024 * 1024 +#define HIGHABORT 26 * 1024 * 1024 + +#endif + +#define NUMPAGES 64 * 1024 +#define PAGESIZE 64 * 1024 +#define PAGEBITS 16 +#define OFFSETBITS 0xffff + +int SWI_vector_installed = FALSE; + +#include <stdio.h> + +/***************************************************************************\ +* Get a Word from Memory * +***************************************************************************/ + +static ARMword +GetWord (ARMul_State * state, ARMword address, int check) +{ + if(address < minReadAddress || address + 4 > (state->MemSize)) + { + //raise memory access error + state->EndCondition = MemoryBoundsError; + state->Emulate = FALSE; + gdb_log_printf(NULL, "Illegal memory read at 0x%p. ", address); + return 0; + } + else + { + return *((ARMword*) (state->MemDataPtr + address)); + } +} + +/***************************************************************************\ +* Put a Word into Memory * +***************************************************************************/ + +static void +PutWord (ARMul_State * state, ARMword address, ARMword data, int check) +{ + if(address < minWriteAddress || address + 4 > (state->MemSize)) + { + state->Emulate = FALSE; + state->EndCondition = MemoryBoundsError; + gdb_log_printf(NULL, "Illegal memory write at 0x%p. ", address); + } + else + { + *((ARMword*) (state->MemDataPtr + address)) = data; + } +} + +/***************************************************************************\ +* ReLoad Instruction * +***************************************************************************/ + +ARMword +ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_PREFETCHABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + if (address < minReadAddress + || address >= (state->MemSize) + || (address >= minWriteAddress && minWriteAddress != 0)) + { + // Custom SWI, defined in the wrapper of ARMul_OSHandleSWI + return 0xEF000000 | 0x200000; + // ^ SWI ^ SWI number + } + + if ((isize == 2) && (address & 0x2)) + { + /* We return the next two halfwords: */ + ARMword lo = GetWord (state, address, FALSE); + ARMword hi = GetWord (state, address + 4, FALSE); + + if (state->bigendSig == HIGH) + return (lo << 16) | (hi >> 16); + else + return ((hi & 0xFFFF) << 16) | (lo >> 16); + } + + return GetWord (state, address, TRUE); +} + +/***************************************************************************\ +* Initialise the memory interface * +***************************************************************************/ + +unsigned +ARMul_MemoryInit (ARMul_State * state, unsigned long initmemsize) +{ + ARMword **pagetable; + unsigned page; + + if (initmemsize) + state->MemSize = initmemsize; + + pagetable = (ARMword **) malloc (sizeof (ARMword *) * NUMPAGES); + + if (pagetable == NULL) + return FALSE; + + for (page = 0; page < NUMPAGES; page++) + *(pagetable + page) = NULL; + + state->MemDataPtr = (unsigned char *) pagetable; + + ARMul_ConsolePrint (state, ", 4 Gb memory"); + + return TRUE; +} + +/***************************************************************************\ +* Remove the memory interface * +***************************************************************************/ + +void +ARMul_MemoryExit (ARMul_State * state) +{ + ARMword page; + ARMword **pagetable; + ARMword *pageptr; + + pagetable = (ARMword **) state->MemDataPtr; + for (page = 0; page < NUMPAGES; page++) + { + pageptr = *(pagetable + page); + if (pageptr != NULL) + free ((char *) pageptr); + } + free ((char *) pagetable); + return; +} + +/***************************************************************************\ +* Load Instruction, Sequential Cycle * +***************************************************************************/ + +ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumScycles++; + +#ifdef HOURGLASS + if ((state->NumScycles & HOURGLASS_RATE) == 0) + { + HOURGLASS; + } +#endif + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Load Instruction, Non Sequential Cycle * +***************************************************************************/ + +ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize) +{ + state->NumNcycles++; + + return ARMul_ReLoadInstr (state, address, isize); +} + +/***************************************************************************\ +* Read Word (but don't tell anyone!) * +***************************************************************************/ + +ARMword ARMul_ReadWord (ARMul_State * state, ARMword address) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return ARMul_ABORTWORD; + } + else + { + ARMul_CLEARABORT; + } +#endif + + return GetWord (state, address, TRUE); +} + +/***************************************************************************\ +* Load Word, Sequential Cycle * +***************************************************************************/ + +ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address) +{ + state->NumScycles++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Word, Non Sequential Cycle * +***************************************************************************/ + +ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address) +{ + state->NumNcycles++; + + return ARMul_ReadWord (state, address); +} + +/***************************************************************************\ +* Load Halfword, (Non Sequential Cycle) * +***************************************************************************/ + +ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + state->NumNcycles++; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + return (temp >> offset) & 0xffff; +} + +/***************************************************************************\ +* Read Byte (but don't tell anyone!) * +***************************************************************************/ + +ARMword ARMul_ReadByte (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + return (temp >> offset & 0xffL); +} + +/***************************************************************************\ +* Load Byte, (Non Sequential Cycle) * +***************************************************************************/ + +ARMword ARMul_LoadByte (ARMul_State * state, ARMword address) +{ + state->NumNcycles++; + + return ARMul_ReadByte (state, address); +} + +/***************************************************************************\ +* Write Word (but don't tell anyone!) * +***************************************************************************/ + +void +ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data) +{ +#ifdef ABORTS + if (address >= LOWABORT && address < HIGHABORT) + { + ARMul_DATAABORT (address); + return; + } + else + { + ARMul_CLEARABORT; + } +#endif + + PutWord (state, address, data, TRUE); +} + +/***************************************************************************\ +* Store Word, Sequential Cycle * +***************************************************************************/ + +void +ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumScycles++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store Word, Non Sequential Cycle * +***************************************************************************/ + +void +ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles++; + + ARMul_WriteWord (state, address, data); +} + +/***************************************************************************\ +* Store HalfWord, (Non Sequential Cycle) * +***************************************************************************/ + +void +ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + state->NumNcycles++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char) data, stderr); /* Write Char */ + return; + } +#endif + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 2) ^ (address & 2)) << 3; /* bit offset into the word */ + + PutWord (state, address, + (temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset), + TRUE); +} + +/***************************************************************************\ +* Write Byte (but don't tell anyone!) * +***************************************************************************/ + +void +ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + temp = ARMul_ReadWord (state, address); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; /* bit offset into the word */ + + PutWord (state, address, + (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset), + TRUE); +} + +/***************************************************************************\ +* Store Byte, (Non Sequential Cycle) * +***************************************************************************/ + +void +ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data) +{ + state->NumNcycles++; + +#ifdef VALIDATE + if (address == TUBE) + { + if (data == 4) + state->Emulate = FALSE; + else + (void) putc ((char) data, stderr); /* Write Char */ + return; + } +#endif + + ARMul_WriteByte (state, address, data); +} + +/***************************************************************************\ +* Swap Word, (Two Non Sequential Cycles) * +***************************************************************************/ + +ARMword ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + state->NumNcycles++; + + temp = ARMul_ReadWord (state, address); + + state->NumNcycles++; + + PutWord (state, address, data, TRUE); + + return temp; +} + +/***************************************************************************\ +* Swap Byte, (Two Non Sequential Cycles) * +***************************************************************************/ + +ARMword ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp; + + temp = ARMul_LoadByte (state, address); + ARMul_StoreByte (state, address, data); + + return temp; +} + +/***************************************************************************\ +* Count I Cycles * +***************************************************************************/ + +void +ARMul_Icycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED) +{ + state->NumIcycles += number; + ARMul_CLEARABORT; +} + +/***************************************************************************\ +* Count C Cycles * +***************************************************************************/ + +void +ARMul_Ccycles (ARMul_State * state, unsigned number, ARMword address ATTRIBUTE_UNUSED) +{ + state->NumCcycles += number; + ARMul_CLEARABORT; +} + + +/* Read a byte. Do not check for alignment or access errors. */ + +ARMword +ARMul_SafeReadByte (ARMul_State * state, ARMword address) +{ + ARMword temp, offset; + + temp = GetWord (state, address, FALSE); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; + + return (temp >> offset & 0xffL); +} + +void +ARMul_SafeWriteByte (ARMul_State * state, ARMword address, ARMword data) +{ + ARMword temp, offset; + + temp = GetWord (state, address, FALSE); + offset = (((ARMword) state->bigendSig * 3) ^ (address & 3)) << 3; + + PutWord (state, address, + (temp & ~(0xffL << offset)) | ((data & 0xffL) << offset), + FALSE); +}
Property changes on: trunk/platforms/Cross/plugins/GdbARMPlugin/armulmem.c ___________________________________________________________________ Added: svn:executable + *
Added: trunk/platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c =================================================================== --- trunk/platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c (rev 0) +++ trunk/platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c 2012-08-10 21:28:50 UTC (rev 2583) @@ -0,0 +1,219 @@ +#define COG 1 +#define FOR_COG_PLUGIN 1 + +#include "GdbARMPlugin.h" + +//disassembler +#include <bfd.h> +#include <dis-asm.h> + +#include <stdarg.h> + +//emulator +#include <armdefs.h> +#include <armemu.h> + +ARMul_State* lastCPU = NULL; + + +// These two variables exist, in case there are library-functions which write to a stream. +// In that case, we would write functions which print to that stream instead of stderr or similar +#define LOGSIZE 4096 +static char gdb_log[LOGSIZE+1]; +static int gdblog_index = 0; + +ulong minReadAddress, minWriteAddress; + +// what is that for? + void (*prevInterruptCheckChain)() = 0; + +void +print_state(ARMul_State* state) +{ + printf("NextInstr: %i\ttheMemory: 0x%p\tNumInstrs: 0x%p\tPC: 0x%p\tmode: %i\tEndCondition: %i\tEmulate: %i\n", + state->NextInstr, state->MemDataPtr, + state->NumInstrs, state->Reg[15], + state->Mode, state->EndCondition, + state->Emulate); +} + +void* +newCPU() +{ + if(lastCPU == NULL) ARMul_EmulateInit(); + lastCPU = ARMul_NewState(); + return lastCPU; +} + +int +resetCPU(void* cpu) +{ + unsigned int i, j; + ARMul_State* state = (ARMul_State*) cpu; + // test whether the supplied instance is an ARMul type? + + gdblog_index = 0; + + // reset registers in all modes + for (i = 0; i < 16; i++) + { + state->Reg[i] = 0; + for (j = 0; j < 7; j++) + state->RegBank[j][i] = 0; + } + for (i = 0; i < 7; i++) + state->Spsr[i] = 0; + + ARMul_Reset(state); + return 0; +} + +int +runOnCPU(void *cpu, void *memory, + ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr, ARMword (*run)(ARMul_State*)) +{ + ARMul_State* state = (ARMul_State*) cpu; + lastCPU = state; + + // test whether the supplied instance is an ARMul type? + state->MemDataPtr = (unsigned char*) memory; + state->MemSize = byteSize; + minReadAddress = minAddr; + minWriteAddress = minWriteMaxExecAddr; + + gdblog_index = 0; + + state->EndCondition = NoError; + state->NextInstr = RESUME; + + state->Reg[15] = run(state); + + // collect the PSR from their dedicated flags to have easy access from the image. + ARMul_SetCPSR(state, ARMul_GetCPSR(state)); + + if(state->EndCondition != NoError){ + return state->EndCondition; + } + + return gdblog_index == 0 ? 0 : SomethingLoggedError; +} + +int +singleStepCPUInSizeMinAddressReadWrite(void *cpu, void *memory, + ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr) +{ + return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoInstr); +} + +int +runCPUInSizeMinAddressReadWrite(void *cpu, void *memory, + ulong byteSize, ulong minAddr, ulong minWriteMaxExecAddr) +{ + return runOnCPU(cpu, memory, byteSize, minAddr, minWriteMaxExecAddr, ARMul_DoProg); +} + +// next functions reason for existence is not clear +/* + * Currently a dummy for Bochs. + */ +void +flushICacheFromTo(void *cpu, ulong saddr, ulong eaddr) +{ +#if 0 +# error not yet implemented +#endif +} + +int +gdb_log_printf(void* stream, const char * format, ...) +{ + va_list arg; + int n; + va_start(arg,format); + + if(stream == NULL){ + n = vsnprintf((char*) (&gdb_log) + gdblog_index, LOGSIZE-gdblog_index, format, arg); + gdblog_index = gdblog_index + n; + } else { + vfprintf(stream, format, arg); + } + return 0; +} + +int +disassembleForAtInSize(void *cpu, ulong laddr, + void *memory, ulong byteSize) +{ + gdblog_index = 0; + // ignore the cpu + // start disassembling at laddr relative to memory + // stop disassembling at memory+byteSize + + disassemble_info* dis = (disassemble_info*) calloc(1, sizeof(disassemble_info)); + // void init_disassemble_info (struct disassemble_info *dinfo, void *stream, fprintf_ftype fprintf_func) + init_disassemble_info ( dis, NULL, gdb_log_printf); + + dis->arch = bfd_arch_arm; + dis->mach = bfd_mach_arm_unknown; + + // sets some fields in the structure dis to architecture specific values + disassemble_init_for_target( dis ); + // Given a bfd, the disassembler can find the arch by itself. + // Unfortunately, we don't have bfd-structures, so we have to choose the function by hand. + //disassemble = disassembler( c ); + disassembler_ftype disassembler = print_insn_little_arm; + //other possible functions are listed in opcodes/dissassemble.c + + dis->buffer_vma = 0; + dis->buffer = memory; + dis->buffer_length = byteSize; + + // while-loop for calling single instruction decoding: + unsigned int isize = 0; + size_t pos = laddr; + size_t max_pos = dis->buffer_vma+dis->buffer_length; + + unsigned int size = disassembler((bfd_vma) pos, dis); + + free(dis); + gdb_log[gdblog_index+1] = 0; + + return size; +} + +void +forceStopRunning() +{ + lastCPU->Emulate = STOP; +} + +int +errorAcorn(void) { return 0; } + +char * +getlog(long *len) +{ + *len = gdblog_index; + return gdb_log; +} + +// adding custom Software Interrupts to the ARMulator +unsigned __real_ARMul_OSHandleSWI(ARMul_State*, ARMword); + +unsigned +__wrap_ARMul_OSHandleSWI (ARMul_State * state, ARMword number) +{ + switch(number) + { + case 0x200000: + // This is the SWI number which is returned by our memory interface + // if there is an instruction fetch for an illegal address. + state->Emulate = STOP; + state->EndCondition = MemoryBoundsError; + + // during execution, the pc points the next fetch address, which is 8 byte after the current instruction. + gdb_log_printf(NULL, "Illegal Instruction fetch address (0x%p).", state->Reg[15]-8); + return TRUE; + } + return __real_ARMul_OSHandleSWI(state, number); +}
Property changes on: trunk/platforms/Cross/plugins/GdbARMPlugin/sqGdbARMPlugin.c ___________________________________________________________________ Added: svn:executable + *
Modified: trunk/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h =================================================================== --- trunk/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h 2012-08-10 21:27:56 UTC (rev 2582) +++ trunk/platforms/Cross/plugins/SocketPlugin/SocketPlugin.h 2012-08-10 21:28:50 UTC (rev 2583) @@ -29,6 +29,7 @@ void sqSocketConnectToPort(SocketPtr s, sqInt addr, sqInt port); void sqSocketCreateNetTypeSocketTypeRecvBytesSendBytesSemaID(SocketPtr s, sqInt netType, sqInt socketType, sqInt recvBufSize, sqInt sendBufSize, sqInt semaIndex); void sqSocketCreateNetTypeSocketTypeRecvBytesSendBytesSemaIDReadSemaIDWriteSemaID(SocketPtr s, sqInt netType, sqInt socketType, sqInt recvBufSize, sqInt sendBufSize, sqInt semaIndex, sqInt readSemaIndex, sqInt writeSemaIndex); +void sqSocketCreateRawProtoTypeRecvBytesSendBytesSemaIDReadSemaIDWriteSemaID(SocketPtr s, sqInt domain, sqInt protocol, sqInt recvBufSize, sqInt sendBufSize, sqInt semaIndex, sqInt readSemaIndex, sqInt writeSemaIndex); void sqSocketDestroy(SocketPtr s); sqInt sqSocketError(SocketPtr s); void sqSocketListenOnPort(SocketPtr s, sqInt port);
vm-dev@lists.squeakfoundation.org